Salve !
Sabe aquelas vezes em que você precisa realizar tarefas demoradas no browser do cliente e então você lembra do maravilhoso Cron Jobs ? Pois é, uma excelente ferramenta a nossa disposição. Entretanto, às vezes, certas empresas de hosting (Locaweb é uma) define um horário para funcionamento destas "tarefas agendadas". No caso da Locaweb é das 2 às 3 da matina apenas.
Mas, mas e agora ? Como executar a tal sonhada tarefa "em background" quando não há o Cron Jobs como opção ?
Um pouco de história
Sabemos muito bem que o PHP é server-side e isso significa que o PHP roda no servidor e não no cliente como o Javascript, por exemplo. Entretanto, logo quando eu comecei a programar com PHP eu me perguntava o motivo pelo qual o script era interrompido ao clicar no botão Stop do browser ou então quando eu o fechava já que a ação era no cliente e não no servidor. Tempos depois descobri que nestes eventos, era enviada uma informação ao servidor PHP (via TCP, claro) que de o usuário "abortou" a conexão com ele e o PHP bem esperto que é, parava aquela tarefa.
Entretanto...
O PHP nos permite manipular esse comportamento, ou seja, posso dizer ao PHP que eu quero continuar executando o script mesmo se o cliente nos deixar na voz ! Como uma imagem vale mais do que mil palavras, deixo aos senhores um pequeno vídeo que fiz demonstrando o funcionamento:
Perceba que caso queira redirecionar o usuário para outra página e continuar trabalhando naquela tarefa, você precisa manipular o buffer e os headers da página da forma como coloquei no script, caso contrário, ele irá processar todo o conteúdo e depois sim, redirecionar. Isto por quê, como não estamos enviando nada diretamente ao browser, o Apache espera uma quantidade de dados enviados antes de processar quaisquer headers. Com as funções de buffer do PHP nós podemos mudar também esse comportamento, forçando-lhe a obedecer o header (Location).
Deixo abaixo o código dos dois arquivos usados no vídeo:
-
<?php
-
/**
-
* Connection Handler
-
* @author Hélio Costa e Silva <helio@hlegius.pro.br>
-
* @version 27/03/2009
-
*
-
* @internal teste
-
*/
-
ob_start();
-
ignore_user_abort(true);
-
$n = 1;
-
-
do {
-
error_log('Sequência ' . $n . "\n", 3, 'foobar.txt');
-
$n++;
-
sleep(1);
-
flush();
-
-
if ($n> 35) break;
-
} while (true);
-
?>
-
<?php
-
/**
-
* Connection Handler
-
* @author Hélio Costa e Silva <helio@hlegius.pro.br>
-
* @version 27/03/2009
-
*
-
* @internal teste
-
*/
-
$n = 30;
-
-
do {
-
if ($n == 36) {
-
header ("Location: http://localhost/estudos/");
-
ob_end_clean();
-
header ("Connection: close");
-
ignore_user_abort(true);
-
ob_start();
-
header("Content-Length: 0");
-
ob_end_flush();
-
flush();
-
// Se houver sessões em aberto, usar também:
-
//session_write_close();
-
// Sugestão feita pelo usuário em:
-
// http://br.php.net/manual/en/features.connection-handling.php
-
}
-
-
error_log('Redirecionado ' . $n . "\n", 3, 'foobar.txt');
-
$n++;
-
sleep(1);
-
-
if ($n> 65) break;
-
} while (true);
-
?>
E também, o vídeo original no formato OGV.
Mais informações:
Nota: o programa usado para gravar foi o qt-RecordMyDesktop para Linux.






Locaweb e ruim demais!
O vídeo ficou legal, bem claro.
Já tinha visto isso em algum lugar, mas esqueci de marcar…
Fala cara.
Passando pra deixar um abraço só!
Isso também pode ser feito via SSH com o comando “nohup” que permite que o sistema continue rodando a aplicação mesmo que o usuário desconecte do servidor.
Não é uma alternativa ao cronjob por não permitir agendamento de tarefas para determinado tempo.
Bom tarde, entendi o comando, muito bom, mas funcionaria para um UPLOAD por exemplo ? creio que não pois há a necessidade do browsercliente estar aberto, certo ? outra dúvida é qual comando utilizar no cronjob para que ele lê o .php e o script continue todo o trabalho (como por exemplo (às 02 da matina) chamar o primeiro script que desencadeia outros scripts independente do horário) seria uma driblada na cron da locaweb… e ai? que comando?
valeu
Seria legal um script puxar outro via include ou por javascript talvez, qual o comando na CRON ?