Как запустить 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

Надеюсь, что это поможет вам

Другие вопросы по тегам