2009-03-08 1 views
4

У меня есть HTML-форма, которая отправляется на страницу PHP, которая инициирует скрипт. Скрипт может занять от 3 секунд до 30 секунд для запуска - пользователю не нужно быть рядом для завершения этого сценария.Abandon Long Processes в PHP (но позвольте им заполнить)

Возможно ли инициировать PHP-скрипт, сразу же распечатать «Спасибо» пользователю (или что-то еще) и позволить им идти своим весельем, пока ваш скрипт продолжает работать?

В моем конкретном случае я отправляю данные формы в php-скрипт, который затем отправляет данные во многие другие местоположения. Ожидание успеха всех должностей в настоящее время не в моих интересах. Я просто хотел бы запустить скрипт, позволить пользователю идти и делать все, что им нравится, и все.

ответ

0

В итоге я получил следующее.

<?php 

    // Ignore User-Requests to Abort 
    ignore_user_abort(true); 
    // Maximum Execution Time In Seconds 
    set_time_limit(30); 

    header("Content-Length: 0"); 
    flush(); 

    /* 

    Loooooooong process 

    */ 

?> 
2

Поместите долгосрочную работу в другой PHP скрипт, например

background.php:

sleep(10); 
file_put_contents('foo.txt',mktime()); 

foreground.php

$unused_but_required = array(); 
proc_close(proc_open ("php background.php &", array(), $unused_but_required)); 
echo("Done); 

Вы увидите "Готово" немедленно, и файл будет написан через 10 секунд.

Я думаю, что proc_close работает, потому что мы даем proc_open никаких труб и никаких дескрипторов файлов.

+0

Не могли бы вы быть более наглядными в своем ответе? – Sampson

+0

Не могли бы вы объяснить, как это работает? Похоже, он пытается закрыть процесс сразу после его открытия. Согласно документации proc_close, она будет ждать завершения процесса - разве это не то, чего мы хотели избежать? – thomasrutter

+0

Я использую этот метод для потоковой обработки и отлично работает –

0

Вы можете попробовать выходной буфер функцию flush и связанные с ними немедленно отправить все, что находится в буфере в браузер:

1

В сценариях можно установить:

<?php 
ignore_user_abort(true); 

Таким образом, сценарий будет не прекращается, когда пользователь покидает страницу. Однако будьте очень осторожны при объединении этого вопроса

set_time_limit(0); 

С тех пор сценарий может выполняться вечно.

1

Вы можете использовать set_time_limit и ignore_user_abort, но, как правило, я бы порекомендовал вам поставить задание в очередь и использовать асинхронный скрипт для его обработки. Это гораздо более простой и прочный дизайн.

0

Theres обертка API вокруг pcntl_fork() называется php_fork.

Но также этот вопрос был на Daily WTF ... не забивайте гвоздь стеклянной бутылкой.

Смежные вопросы