I have a process intensive task that I would like to run in the background.
我有一个进程密集型的任务,我想在后台运行。
The user clicks on a page, the PHP script runs, and finally, based on some conditions, if required, then it has to run a shell script, E.G.:
用户点击一个页面,PHP脚本运行,最后,根据某些条件,如果需要,它必须运行shell脚本,例如:
shell_exec('php measurePerformance.php 47 844 email@yahoo.com');
Currently I use shell_exec, but this requires the script to wait for an output. Is there any way to execute the command I want without waiting for it to complete?
目前我使用shell_exec,但是这需要脚本等待输出。有什么方法可以在不等待它完成的情况下执行我想要的命令吗?
9 个解决方案
#1
123
How about adding.
如何添加。
"> /dev/null 2>/dev/null &"
shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /dev/null 2>/dev/null &');
Note this also gets rid of the stdio and stderr.
注意,这也去掉了stdio和stderr。
#2
18
This will execute a command and disconnect from the running process. Of course, it can be any command you want. But for a test, you can create a php file with a sleep(20) command it.
这将执行一个命令,并断开与正在运行的进程的连接。当然,它可以是任何你想要的命令。但是对于测试,您可以使用sleep(20)命令创建一个php文件。
exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");
#3
11
You can also give your output back to the client instantly and continue processing your PHP code afterwards.
您还可以立即将输出返回给客户端,然后继续处理PHP代码。
This is the method I am using for long-waiting Ajax calls which would not have any effect on client side:
这是我正在使用的方法,用于长时间等待的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.
You can find the detailed explanation here: http://oytun.co/response-now-process-later
您可以在这里找到详细的解释:http://oytun.co/response-now-process-later
#4
8
On Windows 2003, to call another script without waiting, I used this:
在Windows 2003上,无需等待就可以调用另一个脚本,我使用了以下方法:
$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg";
pclose(popen($commandString, 'r'));
This only works AFTER giving changing permissions on cmd.exe
- add Read and Execute for IUSR_YOURMACHINE
(I also set write to Deny).
这只在对cmd授予更改权限后才有效。exe -为IUSR_YOURMACHINE添加Read和Execute(我还设置write to Deny)。
#5
5
Use PHP's popen
command, e.g.:
使用PHP的popen命令,例如:
pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));
This will create a child process and the script will excute in the background without waiting for output.
这将创建一个子进程,脚本将在后台执行,而不需要等待输出。
#6
2
That will work but you will have to be careful not to overload your server because it will create a new process every time you call this function which will run in background. If only one concurrent call at the same time then this workaround will do the job.
这将会起作用,但你必须小心不要让你的服务器超载,因为它会在每次调用这个函数时创建一个新的进程。如果同时只有一个并发调用,那么这个变通方法就可以完成这项工作。
If not then I would advice to run a message queue like for instance beanstalkd/gearman/amazon sqs.
如果没有,我建议运行一个消息队列,例如beanstalkd/gearman/amazon sqs。
#7
1
If it's off of a web page, I recommend generating a signal of some kind (dropping a file in a directory, perhaps) and having a cron job pick up the work that needs to be done. Otherwise, we're likely to get into the territory of using pcntl_fork()
and exec()
from inside an Apache process, and that's just bad mojo.
如果它不在web页面上,我建议生成某种信号(可能在目录中删除文件),并让cron作业接收需要完成的工作。否则,我们可能会在Apache进程中使用pcntl_fork()和exec(),这是一种糟糕的魔咒。
#8
1
For windows
you can use:
对于windows,你可以使用:
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);
Note:
注意:
If you get a COM
error, add the extension to your php.ini
and restart apache
:
如果出现COM错误,请将扩展添加到php中。ini和重新启动apache:
[COM_DOT_NET]
extension=php_com_dotnet.dll
#9
-2
You could always post over some AJAX to a page that calls the shell_exec().
您总是可以通过一些AJAX发布到调用shell_exec()的页面。
#1
123
How about adding.
如何添加。
"> /dev/null 2>/dev/null &"
shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /dev/null 2>/dev/null &');
Note this also gets rid of the stdio and stderr.
注意,这也去掉了stdio和stderr。
#2
18
This will execute a command and disconnect from the running process. Of course, it can be any command you want. But for a test, you can create a php file with a sleep(20) command it.
这将执行一个命令,并断开与正在运行的进程的连接。当然,它可以是任何你想要的命令。但是对于测试,您可以使用sleep(20)命令创建一个php文件。
exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");
#3
11
You can also give your output back to the client instantly and continue processing your PHP code afterwards.
您还可以立即将输出返回给客户端,然后继续处理PHP代码。
This is the method I am using for long-waiting Ajax calls which would not have any effect on client side:
这是我正在使用的方法,用于长时间等待的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.
You can find the detailed explanation here: http://oytun.co/response-now-process-later
您可以在这里找到详细的解释:http://oytun.co/response-now-process-later
#4
8
On Windows 2003, to call another script without waiting, I used this:
在Windows 2003上,无需等待就可以调用另一个脚本,我使用了以下方法:
$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg";
pclose(popen($commandString, 'r'));
This only works AFTER giving changing permissions on cmd.exe
- add Read and Execute for IUSR_YOURMACHINE
(I also set write to Deny).
这只在对cmd授予更改权限后才有效。exe -为IUSR_YOURMACHINE添加Read和Execute(我还设置write to Deny)。
#5
5
Use PHP's popen
command, e.g.:
使用PHP的popen命令,例如:
pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));
This will create a child process and the script will excute in the background without waiting for output.
这将创建一个子进程,脚本将在后台执行,而不需要等待输出。
#6
2
That will work but you will have to be careful not to overload your server because it will create a new process every time you call this function which will run in background. If only one concurrent call at the same time then this workaround will do the job.
这将会起作用,但你必须小心不要让你的服务器超载,因为它会在每次调用这个函数时创建一个新的进程。如果同时只有一个并发调用,那么这个变通方法就可以完成这项工作。
If not then I would advice to run a message queue like for instance beanstalkd/gearman/amazon sqs.
如果没有,我建议运行一个消息队列,例如beanstalkd/gearman/amazon sqs。
#7
1
If it's off of a web page, I recommend generating a signal of some kind (dropping a file in a directory, perhaps) and having a cron job pick up the work that needs to be done. Otherwise, we're likely to get into the territory of using pcntl_fork()
and exec()
from inside an Apache process, and that's just bad mojo.
如果它不在web页面上,我建议生成某种信号(可能在目录中删除文件),并让cron作业接收需要完成的工作。否则,我们可能会在Apache进程中使用pcntl_fork()和exec(),这是一种糟糕的魔咒。
#8
1
For windows
you can use:
对于windows,你可以使用:
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);
Note:
注意:
If you get a COM
error, add the extension to your php.ini
and restart apache
:
如果出现COM错误,请将扩展添加到php中。ini和重新启动apache:
[COM_DOT_NET]
extension=php_com_dotnet.dll
#9
-2
You could always post over some AJAX to a page that calls the shell_exec().
您总是可以通过一些AJAX发布到调用shell_exec()的页面。