Вопрос по redirect, php, header – Как заставить редирект произойти до того, как скрипт php завершится?

9

Я хочу запустить php-скрипт, который будет отправлять кучу электронных писем (новостных рассылок), но так как для его запуска может потребоваться некоторое время, я хочу, чтобы пользователь был немедленно перенаправлен на страницу с сообщением, подобным & quot; Ваши новостные рассылки помещены в очередь на быть отправленным. & quot;
Пока что перенаправления заголовка работают, но они не вызывают перенаправление до тех пор, пока не будут отправлены все письма. Могу ли я закрыть соединение после отправки перенаправления, чтобы браузер сразу же начал переадресацию? Я пробовал такие вещи, как это

<code>
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();
</code>

в различных перестановках и комбинациях, но безрезультатно. Я подозреваю, что это не может быть сделано так просто, но перед тем, как я начну возиться с заданиями cron или пользовательскими демонами, я подумал, что я рассмотрю этот подход. Спасибо

например, как болван предлагает ниже, но не повезло

<code>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(); </code>

Ваш Ответ

7   ответов
14

ражать некоторые выходные данные, почему бы вам не использовать 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,
    //.......
    //.......
?>
это работает для тебя, я только что попробовал, и это не сработало, есть ли какие-то складки, которые я пропускаю? lost baby
Я на самом деле не хочу выводить данные из этого скрипта в браузер, я хочу, чтобы скрипт продолжил обработку после того, как произойдет перенаправление (медленная отправка электронных писем). Возможно, я попытаюсь выполнить отдельный скрипт, но, похоже, это может вызвать проблемы с безопасностью. lost baby
сейчас это кажется самым простым, я, наверное, сделаю это. Я действительно не хотел, потому что сайт не использует много Ajax, и поэтому это изменение стиля. Благодарност lost baby
Вы можете использовать его альтернативу; смотри мой отредактированный ответ ... Bhavesh Gangani
Я хотел бы добавить, что IE7 не будет работать должным образом при наличии сжатия вывода на сервер ... В моем случае мне пришлось добавить эти две строки:apache_setenv('no-gzip', 1); ini_set('zlib.output_compression', 0); Надеюсь, это сэкономит кому-то часы, которые я провел. Salketer
6

Я бы попробовал это:

<?php
header("Location: waitforit.php?msg=Newsletters queued up, will send soon.");
header("Content-Length: 0");
header("Connection: close");
flush();
//Do work here
?>
3

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 ();

?>
1

Content-Length до 0

Просто попробовал, но не повезло. lost baby
Также попробуйConnection: close, видеть Php.net / ручной / EN / features.connection-handling.php # 104541 blockhead
1

вам нужно использовать isapi сresponseBufferLimit="0" в вашем web.config и output_buffering = Off в php.ini, тогда что-то вроде этого должно работать ...

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

0

вы ищете асинхронное выполнение работы. Я хотел бы, чтобы скрипт php создал другой поток (или процесс), который отправляет электронные письма асинхронно. Таким образом, поток, в котором выполняется запрос, не привязан к обработке электронных писем. Поток, обрабатывающий запрос и возвращающий результат, может работать совершенно отдельно от потока, отправляющего электронные письма.

Этот поток, кажется, касается этого подхода, возможно, он будет более полезным в отношении деталей реализации: Выполнить PHP-задачу асинхронно

Похожие вопросы