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

これを行う適切な方法は次のとおりです...SoniaDesbiensによるコード、別名:fataqui 2005/07/01

<?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

Content-Length0に設定してみてください

于 2012-05-08T19:01:34.407 に答える
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

受け入れられた答えは私にはうまくいきませんでしたが、これはうまくいきました。php.iniでignore_user_abort()をオンにする必要があることに注意してください

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 に答える
0

基本的に、あなたは非同期的に仕事を実行しようとしています。phpスクリプトで、電子メールを非同期に送信する別のスレッド(またはプロセス)を作成します。このように、リクエストが実行されているスレッドは、電子メールの処理に関連付けられていません。リクエストを処理して結果を返すスレッドは、メールを送信しているスレッドとは完全に独立して動作できます。

このスレッドはこのアプローチに触れているようです。おそらく、実装の詳細に関してもっと役立つでしょう。PHPタスクを非同期で実行する

于 2012-05-08T20:24:07.167 に答える