Ответ 1
Как насчет добавления.
"> /dev/null 2>/dev/null &"
shell_exec('php measurePerformance.php 47 844 [email protected] > /dev/null 2>/dev/null &');
Обратите внимание, что это также избавляет от stdio и stderr.
У меня есть задача с интенсивным процессом, которую я хотел бы запустить в фоновом режиме.
Пользователь нажимает на страницу, запускает PHP script и, наконец, на основе некоторых условий, если требуется, тогда он должен запускать оболочку script, E.G.:
shell_exec('php measurePerformance.php 47 844 [email protected]');
В настоящее время я использую shell_exec, , но для этого требуется, чтобы script ожидал вывода. Есть ли способ выполнить команду, я хочу без ждать ее завершения?
Как насчет добавления.
"> /dev/null 2>/dev/null &"
shell_exec('php measurePerformance.php 47 844 [email protected] > /dev/null 2>/dev/null &');
Обратите внимание, что это также избавляет от stdio и stderr.
Это приведет к выполнению команды и отключению от выполняемого процесса. Конечно, это может быть любая команда, которую вы хотите. Но для теста вы можете создать файл php с командой sleep (20).
exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");
Вы также можете немедленно вернуть свой результат клиенту и продолжить обработку своего PHP-кода.
Это метод, который я использую для долгожданных вызовов Ajax, которые не будут иметь никакого эффекта на стороне клиента:
ob_end_clean();
ignore_user_abort();
ob_start();
header("Connection: close");
echo json_encode($out);
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
// execute your command here. client will not wait for response, it already has one above.
Подробное объяснение можно найти здесь: http://oytun.co/response-now-process-later
В Windows 2003 для вызова другого script без ожидания я использовал это:
$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg";
pclose(popen($commandString, 'r'));
Это работает только после того, как вы меняете разрешения на cmd.exe
- добавьте Read и Execute для IUSR_YOURMACHINE
(я также установил write to Deny).
Используйте команду PHP popen
, например:
pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));
Это создаст дочерний процесс, а script выйдет в фоновом режиме, не дожидаясь выхода.
Это будет работать, но вы должны быть осторожны, чтобы не перегружать сервер, потому что он будет создавать новый процесс каждый раз, когда вы вызываете эту функцию, которая будет работать в фоновом режиме. Если одновременно выполняется только один одновременный вызов, это обходное решение будет выполнять эту работу.
Если нет, я бы посоветовал запустить очередь сообщений, например, beanstalkd/gearman/amazon sqs.
Если он отключен от веб-страницы, я рекомендую создать какой-либо сигнал (возможно, удалить файл в каталоге) и получить задание cron за работу, которая должна быть выполнена. В противном случае мы, вероятно, попадаем на территорию с использованием pcntl_fork()
и exec()
изнутри процесса Apache, и это просто плохое mojo.
Для windows
вы можете использовать:
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);
Примечание:
Если вы получаете ошибку COM
, добавьте расширение в свой php.ini
и перезапустите apache
:
[COM_DOT_NET]
extension=php_com_dotnet.dll
Вы всегда можете публиковать через AJAX страницу, вызывающую shell_exec().