Alternativa ao Cron Jobs em PHP

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:

CODE:
  1. <?php
  2. /**
  3. * Connection Handler
  4. * @author Hélio Costa e Silva <helio@hlegius.pro.br>
  5. * @version 27/03/2009
  6. *
  7. * @internal teste
  8. */
  9. ob_start();
  10. ignore_user_abort(true);
  11. $n = 1;
  12.  
  13. do {
  14.     error_log('Sequência ' . $n . "\n", 3, 'foobar.txt');
  15.     $n++;
  16.     sleep(1);
  17.     flush();
  18.  
  19.     if ($n> 35) break;
  20. } while (true);
  21. ?>

CODE:
  1. <?php
  2. /**
  3. * Connection Handler
  4. * @author Hélio Costa e Silva <helio@hlegius.pro.br>
  5. * @version 27/03/2009
  6. *
  7. * @internal teste
  8. */
  9. $n = 30;
  10.  
  11. do {
  12.     if ($n == 36) {
  13.         header ("Location: http://localhost/estudos/");
  14.         ob_end_clean();
  15.         header ("Connection: close");
  16.         ignore_user_abort(true);
  17.         ob_start();
  18.         header("Content-Length: 0");
  19.         ob_end_flush();
  20.         flush();
  21.         // Se houver sessões em aberto, usar também:
  22.         //session_write_close();
  23. // Sugestão feita pelo usuário em:
  24. // http://br.php.net/manual/en/features.connection-handling.php
  25.     }
  26.  
  27.     error_log('Redirecionado ' . $n . "\n", 3, 'foobar.txt');
  28.     $n++;
  29.     sleep(1);
  30.  
  31.     if ($n> 65) break;
  32. } while (true);
  33. ?>

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.



5 comentários para “Alternativa ao Cron Jobs em PHP”

  1. Locaweb e ruim demais!
    O vídeo ficou legal, bem claro.
    Já tinha visto isso em algum lugar, mas esqueci de marcar…

  2. Allan Bruno says:

    Fala cara.
    Passando pra deixar um abraço só!

  3. André Taiar says:

    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.

  4. Cuca Doida says:

    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

  5. Marcelo Coimbra says:

    Seria legal um script puxar outro via include ou por javascript talvez, qual o comando na CRON ?

Comente !

Get Adobe Flash playerPlugin by wpburn.com wordpress themes