Pergunta sobre redirect, php, header – Como causar um redirecionamento para ocorrer antes de terminar o script php?

9

Eu quero executar um script php que irá enviar um monte de e-mails (newsletters), mas uma vez que pode demorar um pouco para que isso seja executado, eu quero que o usuário seja imediatamente redirecionado para uma página com uma mensagem como "Seus boletins são enfileirados enviado. "
Até agora, o cabeçalho redireciona o trabalho, mas eles não causam o redirecionamento até que todos os emails sejam enviados. Posso fechar a conexão depois de enviar o redirecionamento para que o navegador atue no redirecionamento imediatamente? Eu tentei coisas assim

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

em várias permutações e combinações, mas sem sucesso. Eu suspeito que isso não pode ser feito de forma simples, mas antes de começar a mexer com tarefas do cron ou daemons personalizados, pensei em analisar essa abordagem. obrigado

por exemplo, como blockhead sugere abaixo, mas sem sorte

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

Sua resposta

7   a resposta
3

aka: fataqui 07/01/2005

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

?>
</code>
6

Eu tentaria isso:

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

você está olhando para executar o trabalho de forma assíncrona. Eu teria o script php criar outro segmento (ou processo) que envia os e-mails de forma assíncrona. Dessa forma, o thread em que a solicitação está sendo executada não está vinculado ao processamento dos emails. O encadeamento que está processando a solicitação e retornando o resultado pode operar completamente separadamente do encadeamento que está enviando os e-mails.

Este tópico parece estar tocando nesta abordagem, talvez seja mais útil em relação aos detalhes da implementação:Execute a tarefa PHP de forma assíncrona

1

Content-Length para 0

Apenas tentei, mas sem sorte. lost baby
Tente tambémConnection: close, Vejophp.net/manual/pt/features.connection-handling.php#104541 blockhead
14

lguma saída, então, por que você não usa um pedido de ajax para o servidor que pode enfileirar e-mails e ainda permitir que o usuário continue a navegar nessa página.

Se você não quiser usar isso; em vez disso você poderia usar, o script é executado em segundo plano mesmo que o usuário seja redirecionado parashow_usermessage.php página

<code><?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,
    //.......
    //.......
?>
</code>
Você é muito bem-vindo, feliz que funcionou para você Bhavesh Gangani
ignore_user_abort () deve ser ativado no php.ini. Ainda assim, a resposta aceita não funcionou para mim. Por favor, veja minha resposta. Doug Cassidy
interessante, vou tentar isso. Obrigado. lost baby
isso funciona para você, eu apenas tentei e não funcionou, há alguma ruga para isso que eu estou sentindo falta? lost baby
1

mas isso aconteceu. Por favor, note que o ignore_user_abort () deve ser ativado em php.ini

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

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

1

você precisa estar usando o isapi comresponseBufferLimit="0" no seu web.config e output_buffering = Desligado no php.ini, então algo assim deveria funcionar ...

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

Perguntas relacionadas