создание фоновых процессов в php для продолжительного процесса

Хорошо, простите меня, если это повторение другого вопроса, но после поиска я не нашел четкого ответа. В основном я хочу, чтобы мое веб-приложение php отключилось от какого-либо события (например, генератора электронной почты или генератора отчетов), которое может занять несколько минут и немедленно вернуть управление на страницу. Я родом из мира .NET, где это можно легко выполнить с помощью потока.

Итак, вот рабочий процесс:

  1. Пользователь нажимает кнопку «Создать отчет»
  2. ajax-вызов, сделанный в «../blah/generate-report» и немедленно возвращается
  3. процесс запускается и продолжается до тех пор, пока пользователь не сможет продолжить свой бизнес
  4. Пользователь может вернуться на страницу отчета и увидеть прогресс: «Отчет завершен на 50%»

Каков наилучший способ сделать это? Краткие ответы в порядке. Мне не нужен код, написанный для меня, просто руководство. Я посмотрел на shell_exec, но я не уверен, что если это лучший способ или если это так, как использовать его для обработки функций в веб-приложении. (Я использую структуру Yii, если это имеет значение). Благодарю.

Джейсон

Лучший (и только AFAIK) способ начать новый поток потоков, как в PHP, – это создать новый запрос PHP, используя что-то вроде curl.

 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://www.yoursite.com/background-script.php'); curl_setopt($ch, CURLOPT_FRESH_CONNECT, true); curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1); curl_exec($ch); curl_close($ch); 

Это запустит скрипт и сразу вернет страницу. Конечно, нет обратного вызова, поэтому лучше всего поставить вывод background-script.php в базу данных, а затем периодически пинговать базу данных с клиента до тех пор, пока не увидите результаты.

Насколько я помню, shell_exec или exec блокируют выполнение вашего PHP-скрипта до тех пор, пока процесс не завершится. Решение состоит в том, чтобы добавить «&» в конце вашей команды, ваш сценарий / программа будет зашифрована.

 "/usr/report.sh &" 

Я использовал что-то вроде этого, чтобы запускать внешний инструмент с PHP, но передавая промежуточным скриптом для управления PID, количеством экземпляров … Не могу сказать, работает ли он под хостом Windows.

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

 public function redirectAndContinue( $url ) { ignore_user_abort(true); header("Location: $url"); header("Connection: close"); header("Content-Length: 0"); flush(); } 

Вы можете использовать его так

 // do quick basic stuff to validate your report $this->redirectAndContinue( $url ) // send your email or do other slow stuff 

Проблема в том, что он не работает с AJAX, это должен быть регулярный запрос страницы (возможно, с POST). Но вы можете сделать индикатор выполнения в любом случае: сохранить что-то в своей базе данных или сеансе, а затем продолжить вызов некоторого URL-адреса, чтобы получить прогресс через AJAX.

Могу я предложить Гирмана? Вы можете отправлять задания на сервер ретранслятора и запрашивать статус.

Gearman предоставляет распределенную платформу приложений для работы с несколькими машинами или процессами. Он позволяет приложениям выполнять задачи параллельно, обрабатывать баланс нагрузки и вызывать функции между языками. Структура может использоваться в различных приложениях. Gearman является многопоточным и, как известно, способен выполнять 50 тысяч рабочих мест в секунду.

Быстрый учебник находится здесь: http://www.sitepoint.com/introduction-gearman-multi-tasking-php/

Его также довольно легко начать, и весь ваш код будет в PHP.