10

我想运行一个 php 脚本,它会发送一堆电子邮件(通讯),但由于它可能需要一段时间才能运行,我希望用户立即被重定向到一个页面,其中包含类似“您的通讯已排队等待”的消息送出。”
到目前为止,标头重定向有效,但直到所有电子邮件都发送完毕后才会导致重定向。我可以在发送重定向后关闭连接,以便浏览器立即执行重定向吗?我试过这样的东西


ob_start();
ignore_user_abort(true);
header( "refresh:1;url=waitforit.php?msg=Newsletters queued up, will send soon.");
header("Connection: close");
header("Content-Length: " . mb_strlen($resp));
echo $resp;
//@ob_end_clean();
ob_end_flush();
flush();

各种排列组合,但无济于事。我怀疑它不能这么简单,但在我开始搞乱 cron 作业或自定义守护进程之前,我想我会研究这种方法。谢谢

例如,就像下面的笨蛋建议的那样,但没有运气

ob_start();
ignore_user_abort(true);
header( "refresh:1;url=mailing_done.php?msg=Newsletters queued for sending.");
header("Connection: close");
header("Content-Length: 0" );
//echo $resp;
ob_end_flush();
flush(); 

4

7 回答 7

15

如果你想连续运行脚本并且仍然想显示一些输出,为什么不使用 ajax 请求到服务器,它可以排队邮件并仍然让用户继续浏览该页面。

如果您不想使用它;相反,您可以使用, 即使用户将被重定向到show_usermessage.php页面,脚本也会在后台运行

<?PHP
    //Redirect to another file that shows that mail queued
    header("Location: show_usermessage.php");

    //Erase the output buffer
    ob_end_clean();

    //Tell the browser that the connection's closed
    header("Connection: close");

    //Ignore the user's abort (which we caused with the redirect).
    ignore_user_abort(true);
    //Extend time limit to 30 minutes
    set_time_limit(1800);
    //Extend memory limit to 10MB
    ini_set("memory_limit","10M");
    //Start output buffering again
    ob_start();

    //Tell the browser we're serious... there's really
    //nothing else to receive from this page.
    header("Content-Length: 0");

    //Send the output buffer and turn output buffering off.
    ob_end_flush();
    flush();
    //Close the session.
    session_write_close();


    //Do some of your work, like the queue can be ran here,
    //.......
    //.......
?>
于 2012-05-08T19:09:03.867 回答
7

我会试试这个:

<?php
header("Location: waitforit.php?msg=Newsletters queued up, will send soon.");
header("Content-Length: 0");
header("Connection: close");
flush();
//Do work here
?>
于 2012-05-08T19:37:38.727 回答
3

这是正确的方法...... Sonia Desbiens 的代码,又名:fataqui 07/01/2005

<?php

set_time_limit ( 0 );

/* start the forced redirect */

header ( 'Connection: close' );

ob_start ();

/* close out the server process, release to the client */

header ( 'Content-Length: 0' );

header ( 'Location: /page_to_redirect_to.php' );

ob_end_flush ();

flush ();

/* end the forced redirect and continue with this script process */

ignore_user_abort ( true );

/* the rest of your script here */

/*
 * this example will redirect the user to '/page_to_redirect_to.php'
 * then this script will continue by sleeping for '10' seconds, then
 * this script will write a file, and then this script will exit...
*/

sleep ( 10 );

file_put_contents ( './out.txt', '' );

exit ();

?>
于 2012-11-08T00:06:10.987 回答
1

要让它在 IIS7 上工作,您需要responseBufferLimit="0"在 web.config 中使用 isapi 并在 php.ini 中使用 output_buffering=Off,然后这样的东西应该可以工作......

  session_write_close();
  header( "Location: ".$sURL ) ;
    // try to allow continued processing
  if(ob_get_length())
    ob_end_clean();
  header("Connection: close");
  ignore_user_abort(); // optional
  ob_start();
  header("Content-Length: 0");
  ob_end_flush(); // Strange behaviour, will not work
  flush(); // Unless both are called !
于 2012-10-16T14:23:29.930 回答
1

接受的答案对我不起作用,但确实如此。请注意,ignore_user_abort() 必须在 php.ini 中开启

ignore_user_abort(true);
    session_write_close(); // optional, this will close the session.
    header("Location: $url");
    header("Content-Length: 0");
    ob_end_flush();
    flush();
    //do_function_that_takes_five_mins();

http://waynepan.com/2007/10/11/how-to-use-ignore_user_abort-to-do-process-out-of-band/

于 2013-07-24T19:19:40.667 回答
1

尝试设置Content-Length为 0

于 2012-05-08T19:01:34.407 回答
0

基本上,您希望异步执行这项工作。我会让 php 脚本创建另一个异步发送电子邮件的线程(或进程)。这样,运行请求的线程就不会与电子邮件的处理相关联。处理请求并返回结果的线程可以完全独立于发送电子邮件的线程运行。

这个线程似乎正在触及这种方法,也许它对实现细节会更有帮助:Run PHP Task Asynchronously

于 2012-05-08T20:24:07.167 回答