Pergunta
Eu estou tentando fazer um script PHP, tenho o script terminou mas leva como 10 minutos para terminar o processo que se destina a fazer. Este não é um problema, no entanto presumo eu tenho que manter a página carregado todo esse tempo que é irritante. Posso tê-lo assim que eu iniciar o processo e, em seguida, voltar 10 minutos mais tarde e apenas visualizar o arquivo de log tem gerado?
Solução
Bem, você pode usar " ignore_user_abort ( true) "
Assim, o script continuará a trabalhar (manter um olho sobre a duração do roteiro, talvez acrescentar " set_time_limit (0) ")
Mas um aviso aqui: Você não será capaz de parar um script com estas duas linhas:
ignore_user_abort(true);
set_time_limit(0);
A não ser que você pode acessar diretamente o servidor e matar o processo lá! (Estive lá, fiz um loop infinito, que se autodenomina uma e outra vez, fez o servidor chegar a uma paragem brusca, tem gritado ...)
Outras dicas
Parece que você deve ter uma fila e um script externo para o processamento da fila.
Por exemplo, o script PHP deve colocar uma entrada em uma tabela de banco de dados e retornar imediatamente. Em seguida, um cron executando cada minuto verifica a fila e garfos um processo para cada trabalho.
A vantagem aqui é que você não bloquear um fio apache-se por 10 minutos.
Eu tive muitos problemas com este tipo de processo sob janelas; Minha situação era um pouco diferente, em que eu não me importava com a resposta do "script" - Eu queria que o script para iniciar e permitir que outras solicitações de página para percorrer enquanto ele estava ocupado trabalhando fora
.Por alguma razão; Eu tive problemas com ele, quer pendurados outros pedidos ou o tempo limite após cerca de 60 segundos (o apache e php foram estabelecidos para o tempo limite após cerca de 20 minutos); Nota-se também que os tempos firefox fora após 5 minutos (por padrão) de qualquer maneira assim depois desse ponto você pode não saber o que está acontecendo através do browser sem alterar as configurações no Firefox.
Acabei usando o processo de métodos abertos e processo de perto de abrir um php em modo cli assim:
pclose(popen("start php myscript.php", "r"));
Isto (usando start) abrir o processo de php e, em seguida, matar o processo de start deixando php correndo pelo tempo que for necessário - novamente você precisa matar o processo para desligá-lo manualmente para baixo. Não preciso de você para definir quaisquer pedidos de tempo e você pode deixar a página atual que chamou de continuar e saída de mais alguns detalhes.
O único problema com isto é que se você precisa enviar o script quaisquer dados, ou você faria isso através de outra fonte ou passá-lo ao longo da "linha de comando" como parâmetros; que não é tão seguro.
funcionou muito bem para o que precisávamos embora e garante o script sempre começa e é permitido para executar sem quaisquer interrupções.
Isto pode ser útil, também: Asynchronous shell exec em PHP
Eu acho comando shell_exec é o que você está procurando.
No entanto, é desativa em modo de segurança.
O PHP artigo Manual sobre isso é aqui: http://php.net/shell_exec
Há um artigo sobre isso aqui: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/
Não há outra opção que você pode usar, executar o CLI script ... Ele será executado em segundo plano e você ainda pode executá-lo como um cronjob se quiser.
exemplo
> #!/usr/bin/php -q
<?php
//process logs
?>
Isto pode ser configurado como um cronjob e irá executar sem limitação de tempo .... Este exemplo é para o sistema de operação baseado em UNIX embora.
FYI Eu tenho um script php correndo com um loop infinito que faz algum processamento e tem funcionado nos últimos 3 meses sem parar.
Você pode usar ignore_user_abort()
- de que maneira o script continuará a funcionar mesmo se você fechar o navegador ou ir para uma página diferente.
Pense sobre Gearman
Gearman é um framework de aplicação genérica para a agricultura de trabalhos para várias máquinas ou processos. Ele permite que aplicativos para completar tarefas em paralelo, para processamento de balanceamento de carga, e para funções de chamada entre os idiomas. O quadro pode ser usado em uma variedade de aplicações, a partir de sites de alta disponibilidade para o transporte de eventos de replicação de banco de dados.
Esta extensão fornece classes para escrever clientes Gearman e trabalhadores. - Fonte Manual do PHP
site oficial do Gearman
Além de resposta das bastiandoeen você pode combinar ignore_user_abort(true);
com um pedido cUrl .
Falso a definição de uma CURLOPT_TIMEOUT_MS
baixo aborto pedido e manter o processamento após a conexão fechada:
function async_curl($background_process=''){
//-------------get curl contents----------------
$ch = curl_init($background_process);
curl_setopt_array($ch, array(
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER =>true,
CURLOPT_NOSIGNAL => 1, //to timeout immediately if the value is < 1000 ms
CURLOPT_TIMEOUT_MS => 50, //The maximum number of mseconds to allow cURL functions to execute
CURLOPT_VERBOSE => 1,
CURLOPT_HEADER => 1
));
$out = curl_exec($ch);
//-------------parse curl contents----------------
//$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
//$header = substr($out, 0, $header_size);
//$body = substr($out, $header_size);
curl_close($ch);
return true;
}
async_curl('http://example.com/background_process_1.php');
Nota ??strong>
Se você quiser cURL para tempo limite em menos de um segundo, você pode usar CURLOPT_TIMEOUT_MS, embora haja a / "recurso" bug em "Unix-like sistemas" que causa libcurl ao tempo limite imediatamente se o valor for < 1000 ms com o erro "Erro cURL (28): Tempo limite foi atingido". o explicação para este comportamento é:
[...]
A solução é desativar sinais usando CURLOPT_NOSIGNAL
pros
- Não há necessidade de métodos de comutação (compatível com Windows e Linux)
- Não há necessidade de implementar manipulação de conexão via conectores e buffer (Independente de navegador e versão do PHP)
contras
- extensão Necessidade onda
Resources
Zuk.
Eu tenho certeza que isso vai funcionar:
<?php
pclose(popen('php /path/to/file/server.php &'));
echo "Server started. [OK]";
?>
A 'e' é importante. Ela diz ao shell para não aguardar o processo para sair.
Você também pode usar este código em seu php (como "bastiandoeen" disse)
ignore_user_abort(true);
set_time_limit(0);
no seu comando de parada do servidor:
<?php
$output;
exec('ps aux | grep -ie /path/to/file/server.php | awk \'{print $2}\' | xargs kill -9 ', $output);
echo "Server stopped. [OK]";
?>
Apenas chamada StartBuffer () antes de qualquer saída, e EndBuffer () quando você quer o cliente para conexão estreita. O código depois de chamar EndBuffer () será executado no servidor sem conexão do cliente.
private function StartBuffer(){ @ini_set('zlib.output_compression',0); @ini_set('implicit_flush',1); @ob_end_clean(); @set_time_limit(0); @ob_implicit_flush(1); @ob_start(); } private function EndBuffer(){ $size = ob_get_length(); header("Content-Length: $size"); header('Connection: close'); ob_flush();ob_implicit_flush(1); }