Есть ли способ использовать shell_exec, не дожидаясь завершения команды?

У меня сложная задача, которую я хотел бы запустить в фоновом режиме.

Пользователь нажимает на страницу, запускает скрипт PHP и, наконец, на основе некоторых условий, если требуется, тогда он должен запускать сценарий оболочки, EG:

shell_exec('php measurePerformance.php 47 844 email@yahoo.com'); 

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

Как насчет добавления.

 "> /dev/null 2>/dev/null &" shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /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 для вызова другого скрипта без ожидания я использовал это:

 $commandString = "start /bc:\\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).

Используйте команду popen PHP, например:

 pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r")); 

Это создаст дочерний процесс, и скрипт будет работать в фоновом режиме, не дожидаясь выхода.

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

Если нет, то я бы посоветовал запустить очередь сообщений, например, 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 ().