PHP exec() как фоновый процесс (среда Windows Wampserver)

Я пытаюсь настроить файл триггера php, который запустит фоновый процесс. (см. этот вопрос)

Я делаю это в среде Windows Wampserver.

Так, например, у меня есть trigger.php, который запускает функцию exec, которая вызывает мой backgroundProcess.php для анализа и выполнения.

Однако проблема в том, что мой файл trigger.php ожидает, пока команда exec() завершит выполнение backgroundProcess.php, прежде чем она остановится. Фоновый процесс выполняется примерно 20-30 секунд, и trigger.php все это время ждет, пока backgroundProcess.php полностью не завершится.

Это имеет смысл? Вот файл trigger.php, который запускает команду exec()

exec('C:\wamp\bin\php\php'.phpversion().'\php.exe -f C:\path\to\backgroundProcess.php > C:\wamp\bin\php\php'.phpversion().'\dev\null &');

По сути, я хочу, чтобы trigger.php просто запускал фоновый процесс, а не ждал его завершения.


ИЗМЕНИТЬ

Проблема решена следующей командой:

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:\wamp\bin\php\phpVERSIONNUMBER\php-win.exe -f C:/wamp/www/path/to/backgroundProcess.php", 0, false);

person Emmanuel    schedule 20.03.2011    source источник
comment
Это вызывало у меня проблемы случайным образом. Генерация исключений о невозможности выполнить команду. Проверьте мой ответ.   -  person Muhammad Gelbana    schedule 02.09.2013
comment
А что в файле backgroundProcess.php?   -  person user3120717    schedule 29.12.2013


Ответы (6)


Проблема решена следующей командой:

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:\wamp\bin\php\phpVERSIONNUMBER\php-win.exe -f C:/wamp/www/path/to/backgroundProcess.php", 0, false);
person Emmanuel    schedule 20.03.2011
comment
Это вызывало у меня проблемы случайным образом. Генерация исключений о невозможности выполнить команду. Проверьте мой ответ. - person Muhammad Gelbana; 02.09.2013
comment
@Muhammad Gelbana У вас нет ответа на этот вопрос .. Хотите быть немного более конкретным или дать ссылку на ответ, на который вы ссылаетесь? - person computrius; 14.02.2014
comment
Оно было удалено! В любом случае, вот краткое изложение того, что я написал exec("CMD /C start yourcommand here"); I think the /C parameter switch isn't necessary, but I'm just being extra sure. Prefix your command with dirname(__FILE__) if you want to execute in the current directory of the script. This can only work if the start command exists on your windows machine. - person Muhammad Gelbana; 14.02.2014

Пытался добиться того же на сервере Windows 2000 с PHP 5.2.8.

Ни одно из решений не сработало для меня. PHP продолжал ждать ответа.

Нашел решение:

$cmd = "E:\PHP_folder_path\php.exe E:\some_folder_path\backgroundProcess.php";
pclose(popen("start /B ". $cmd, "a"));  // mode = "a" since I had some logs to edit

ps: отправка того же ответа в другой поток (PHP на компьютере с Windows; запуск процесса в фоновом режиме), так как эти 2 ссылки очень помогли мне в некоторых исследованиях по этому вопросу.

person Rohit    schedule 12.04.2013
comment
Я обнаружил, что этот метод отлично работает на Win7 с PHP 5.4. - person JoshuaDavid; 02.01.2015
comment
a не является допустимым режимом для popen(), допустимы только r, w или для двоичных, rb и rw. - person Milad Abooali; 25.02.2021

Из руководства: http://www.php.net/manual/en/function.exec.php

Примечание:

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

И на аналогичный вопрос я ответил: comple/5103561#5103561">Вызвать другой PHP-скрипт и вернуть управление пользователю до завершения другого скрипта

person JohnP    schedule 20.03.2011
comment
@JohnP - Да, но я думал, что делаю это с битом > C:\wamp\bin\php\php'.phpversion().'\dev\null & в конце? - person Emmanuel; 20.03.2011
comment
Я думаю, вам нужно создать дескриптор файла и передать его в качестве второго параметра. Не просто протрубить. - person JohnP; 20.03.2011
comment
@JohnP - я раньше не слышал об дескрипторе файла ... По крайней мере, не об этом термине. Не могли бы вы привести быстрый пример? - person Emmanuel; 20.03.2011
comment
это просто указатель на файл. $fd = fopen('dump.txt', 'a'). Просто причудливый термин для fd :) - person JohnP; 20.03.2011
comment
@JohnP - Нет, добавление дескриптора файла ничего не дало. Но получилось что-то другое, так что проблема решена!!! См. выше редактировать :) - person Emmanuel; 20.03.2011
comment
@Эммануэль, да? хм, может дело в винде. Я думаю, что COM будет работать только в Windows. Кроме того, я думаю, вы должны опубликовать это как ответ и отметить его как принятый, если он сработал для вас. Люди с той же проблемой могут использовать это :) - person JohnP; 20.03.2011

Возможно, вам придется изменить свой подход к реализации. Необходимость ждать так долго будет раздражать пользователя вашего приложения и фатально для всего приложения.

Для таких задач обычно лучше ставить задачу в очередь, в идеале в базе данных, и периодически ее обрабатывать. В системах на базе Linux есть хронические задания. В Windows вы можете использовать планировщик для запуска backgroundProcess.php.

person Shamim Hafiz    schedule 20.03.2011
comment
Это не то, что можно поставить в очередь. Это ssh-соединение с удаленным сервером и обработка некоторых вещей. - person Emmanuel; 20.03.2011

Вполне может быть, что при использовании exec() в среде Windows перенаправление происходит на NUL:. /dev/null — это нулевой файл *nix.

person John    schedule 30.09.2011

В дополнение к ответу Рохита выше я отредактировал его решение для работы в Windows 10 PHP 7.0.3:

pclose(popen("start /B ". $cmd, "w"));
person William N Irwin    schedule 16.08.2017