我想用popen在后台运行一个php脚本。但是,我需要传递一个(相当大)的序列化对象。PHP管道进入后台进程
$cmd = "php background_test.php >log/output.log &";
$fh = popen($cmd, 'w');
fwrite($fh, $data);
fclose($fh);
//pclose($fh);
没有&符此代码执行得很好,但父脚本将等待,直到孩子完成运行。使用&符STDIN不获取数据。
任何想法?
我想用popen在后台运行一个php脚本。但是,我需要传递一个(相当大)的序列化对象。PHP管道进入后台进程
$cmd = "php background_test.php >log/output.log &";
$fh = popen($cmd, 'w');
fwrite($fh, $data);
fclose($fh);
//pclose($fh);
没有&符此代码执行得很好,但父脚本将等待,直到孩子完成运行。使用&符STDIN不获取数据。
任何想法?
据我所知,没有办法在PHP发送后台进程并继续提供其STDIN(但也许我错了)。您这里有另外两个选择:
background_test.php
从命令行得到它的输入和改变你的命令行中php background_test.php arg1 arg2 ... >log/output.log &
background_test.php
脚本与该文件,如以下代码示例点2:
<?
$tmp_file = tempnam();
file_put_content($tmp_file, $data);
$cmd = "php background_test.php < $tmp_name > log/output.log &";
exec($cmd);
你可以尝试让子进程写数据和主脚本继续正常。
像这样的事情
// Fork a child process
$pid = pcntl_fork();
// Unable to fork
if ($pid == -1) {
die('error');
}
// We are the parent
elseif ($pid) {
// do nothing
}
// We are the child
else {
$cmd = "php background_test.php >log/output.log";
$fh = popen($cmd, 'w');
fwrite($fh, $data);
fclose($fh);
exit();
}
// parent will continue here
// child will exit above
了解更多关于在这里:https://sites.google.com/a/van-steenbeek.net/archive/php_pcntl_fork
还要检查功能pcntl_waitpid()(僵尸消失)PHP文档。
使后台进程侦听套接字文件。然后从PHP打开套接字文件并将您的序列化数据发送到那里。当您的后台守护进程通过套接字接收连接时,使其分叉,读取数据然后处理。
你需要做一些阅读,但我认为这是实现这一目标的最好方法。通过套接字我的意思是unix套接字文件,但你也可以在网络上使用它。
http://gearman.org/也是一个不错的选择,因为通过@Joshua
提到真的小心僵尸进程,如果你将要分叉脚本。另一种可能的选择是像Gearman这样的队列管理器。 –
好点,加入了waitpid的参考 –