Извините, но отправка Connection:close
и flush()
- это , а не решение - не переносится между серверами или браузерами.Может показаться, что - решение, потому что оно работает, когда вы запускаете простой тест.Если вы попробуете это с
send_result_to_client();
sleep(60); // simulate a job...
mail(...); // ...ENDING with a mail message
, а затем ничего не сделаете, или, что еще хуже, сделайте то, что сделает любой пользователь - закройте окно, как только он увидит сообщение «Вы получите уведомление по электронной почте» - выВы обнаружите, что на большинстве платформ электронное письмо никогда не отправляется, и работа никогда не выполняется.
curl
может прерваться, если были получены Connection:close
и Content-Length
байты, но из RFC2616 ,
HTTP/1.1 defines the "close" connection option for **the sender** to signal that the connection will be closed after completion of the response.
Но сервер не закрывает соединение, не совсем.Для этого потребуется die()
или exit()
, прежде чем задание будет обработано.
Таким образом, ваш сценарий продолжает выполняться только до тех пор, пока браузер фактически не закроет соединение - в этот момент ( обычно )обработка прерывается.Возможно, на некоторых платформах это не так, но не рассчитывайте на это.
Вы можете попытаться улучшить ситуацию с помощью другого хака:
set_time_limit(VERY_LONG_TIME);
ignore_user_abort();
, но это действительнохак.
По-настоящему портативных решений не существует.Обычно, как предполагает Манаток, задание ставится в очередь где-то еще, а очередь обрабатывается асинхронно другим потоком.Возможно, это лучшее решение.
Другие возможности включают другой и, возможно, более простой способ сделать то же самое, используя atd и at command (или эквивалент в Windows), чтобы поставить задачу в очередь.Вы можете создать «управление заданиями» с помощью shell_exec
, отправив новый PHP-скрипт для выполнения atd
:
shell_exec("echo 'php -q /path/to/script.php \"param1\" \"param2\" | at now");
(или более эффективно, запустив "at now
" с popen
и записать команду для выполнения в stdin
).
См., например:
https://github.com/treffynnon/PHP-at-Job-Queue-Wrapper
Вы также можете попытаться создать параллельное задание через popen
или shell_exec
, но вам нужно отсоединить его от процесса сервера, или вы обнаружите, что система перегружена копиями исполняемого файла задания (или CMD.EXE
, если вы делаете это в Windows).
См .:
Exec асинхронной оболочки в PHP