Хорошо, простите меня, если это повторение другого вопроса, но после поиска я не нашел четкого ответа. В основном я хочу, чтобы мое веб-приложение php отключилось от какого-либо события (например, генератора электронной почты или генератора отчетов), которое может занять несколько минут и немедленно вернуть управление на страницу. Я родом из мира .NET, где это можно легко выполнить с помощью потока.
Итак, вот рабочий процесс:
Каков наилучший способ сделать это? Краткие ответы в порядке. Мне не нужен код, написанный для меня, просто руководство. Я посмотрел на 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.