Как запустить PHP-код в фоновом режиме на Unix-сервере
На моем веб-сайте есть функция загрузки данных пользователями. Эти потоки данных обычно имеют более 30000 записей. И каждая запись должна пройти сложный процесс проверки. Таким образом, эта обработка каналов займет больше 1 часа. Этот длительный процесс неизбежен.
Здесь эти каналы загружены публичным пользователем. И размер канала составляет менее 5 МБ текстового файла. Поэтому мы не хотим предоставлять доступ по FTP, а также не хотим предоставлять доступ к командной строке для этих пользователей. Только мы предпочитаем предоставить веб-доступ для загрузки каналов. И мы должны обработать ленту сразу после их загрузки. И после обработки мы должны отправить им отчет по почте.
Теперь проблема заключается в том, что веб-страницы, работающие в течение длительного времени, вызывают проблемы с тайм-аутом прокси на многих сетевых работах (так как на ответ требуется 1 час). Это проблема большинства сетевых настроек работы клиента.
Мне нужен способ запустить скрипт PHP после загрузки канала. И этот скрипт должен запускаться в фоновом режиме, в то же время правильно завершать загрузку страницы, не задерживая клиента.
Я сделаю фон для обработки данных и отправлю почту клиенту после завершения процесса. Вкладка Cron здесь неосуществима, так как клиент может использовать эту функцию только несколько раз в месяц и в неожиданном диапазоне времени.
Если есть способ запустить скрипт PHP в фоновом режиме, но через веб-доступ, пожалуйста, дайте мне знать.
Пример сценария для упрощения требования
Возьмите этот пример и помогите мне изменить скрипт для достижения результата. У меня есть два сценария PHP "thread.php и createfile.php". Файл с именем "thread.php" будет открыт клиентом через веб-браузер. Этот скрипт должен выполнить скрипт "createfile.php". Но это займет 20 секунд, чтобы ответить. Но мы хотим, чтобы он работал в фоновом режиме. И показать сразу положить в браузере.
Ниже приведен код примера сценариев.
createfile.php ( http://sugunan.net/demo/createfile.php)
<?php
sleep(20);
@unlink("phpfile.txt");
$myfile = fopen("phpfile.txt", "w") or die("Unable to open file!");
$txt = date("h:i:s")."\n";
fwrite($myfile, $txt);
fclose($myfile);
mail("someone@example.com","Background process","Process completed");
?>
созданный файл виден по веб-адресу: http://sugunan.net/demo/phpfile.txt
thread.php ( http://sugunan.net/demo/thread.php)
<pre>
<?php
echo "Script start at: " . date('h:i:s') . "\n";
include("createfile.php"); //give a method to execute this script but in background without delay
echo "Script end at: " . date('h:i:s');
?>
Это даст следующие результаты с sleep()
задержка функции.
Сценарий начинается в: 02:53:27
Конец сценария в: 02:53:47
Есть ли способ выполнить "createfile.php" без include()
метод. И избежать 20 секунд sleep
задержка при обработке файла "createfile.php" в фоновом режиме?
Пожалуйста, примите во внимание, что я хочу избежать времени ожидания на стороне клиента и хочу немедленно выложить вывод в браузер.
3 ответа
Наконец-то я получил рабочий ответ из следующего поста: команда php exec (или аналогичная), чтобы не ждать результата
Поэтому я отредактировал код следующим образом, чтобы выполнить мое требование. Но я не знаю объяснения, как это работает. Я только копирую синтаксис из этого ответа и вставляю его сюда с изменениями.
<?php
echo "Script start at: " . date('h:i:s') . "\n";
exec('bash -c "exec nohup php createfile.php > /dev/null 2>&1 &"');
echo "Script end at: " . date('h:i:s');
?>
Вот php createfile.php
будет командой для выполнения сценария PHP и продолжения без ожидания вывода.
Благодаря Cristian
Используйте exec ()
http://php.net/manual/en/function.exec.php
Это позволит вам запустить длинный процесс в другом потоке. Я использовал это для всех других приложений PHP, Python или C, чтобы конвертировать wav в mp3, конвертировать видео или анализировать большие XML-файлы...
Убедитесь, что он уведомил вас или пользователя, возможно, по электронной почте, когда он завершится, и если это было успешно.
Отредактированный с рабочим кодом на purehuman.info/demo ... он на самом деле пишет файл сейчас. Вот что я хотел бы сделать, чтобы thread.php выглядел так:
<?php
echo "Script start at: " . date('h:i:s') . "\n";
exec("php -f createfile.php /dev/null &");
echo "Script end at: " . date('h:i:s');
?>
Если вы находитесь в Windows:
<?php
echo "Script start at: " . date('h:i:s') . "\n";
exec("start /B php createfile.php"); //obviously change the paths etc where needed..
echo "Script end at: " . date('h:i:s');
?>
нужно отдать должное части Windows: Как выполнить PHP-сценарии в фоновом режиме, используя EXEC() и CMD
PHP не предназначен для такой работы. Но есть хитрости, чтобы попытаться это сделать.
Если в ваших лентах содержится более 30000 записей, у вас будут проблемы с тайм-аутом в PHP FPM. Таким образом, ваш скрипт должен работать с PHP CLI (проверьте параметры сервера на время ожидания PHP CLI).
Вы должны смотреть на Rabbit MQ и программировать работу cron каждую минуту, чтобы consume
сообщения в очереди. Вот пример с PHP http://www.rabbitmq.com/tutorials/tutorial-two-php.html
Надеюсь, что это поможет вам