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


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

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

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

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

9 80

9 ответов:

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

"> /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 /b c:\php\php.EXE C:\Inetpub\wwwroot\mysite.com\phpforktest.php --passmsg=$testmsg"; 
pclose(popen($commandString, 'r'));

это работает только после изменения разрешения cmd.exe - добавить чтение и выполнение для IUSR_YOURMACHINE (Я также установил запись в Deny).

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

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

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

конечно,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

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

Если нет, то я бы посоветовал запустить очередь сообщений, например, beanstalkd/gearman / amazon sqs.

если он находится вне веб-страницы, я рекомендую генерировать какой-то сигнал (возможно, отбрасывая файл в каталог) и иметь задание cron, чтобы выполнить работу, которую необходимо выполнить. В противном случае мы, скорее всего, попадем на территорию использования pcntl_fork() и exec() изнутри процесса Apache, и это просто плохой Моджо.

вы всегда можете разместить над некоторыми AJAX на странице, которая вызывает shell_exec ().