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?

Foi útil?

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

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top