如何异步运行PHP脚本?
问题描述:
我正在创建一个将通过命令行运行的PHP脚本。作为这个脚本的一部分,有时候我可能需要产生/分叉一个可能需要很长时间才能完成的脚本。我不想阻止原始脚本完成。如果我使用JavaScript来完成这项工作,我可以在后台运行AJAX请求。这基本上是我在这里要做的。我不需要知道叉子何时完成,只是他们开始并完成自己。如何异步运行PHP脚本?
如何异步运行这些PHP脚本?
foreach ($lotsOfItems as $item) {
if ($item->needsExtraHelp) {
//start some asynchronous process here, and pass it $item
}
}
答
int pcntl_fork (void)
的pcntl_fork()函数创建一个子过程,从仅在它的PID和PPID父进程不同。请参阅系统的fork(2)手册页,以获取有关fork如何在您的系统上工作的具体细节。
细节:http://php.net/manual/en/function.pcntl-fork.php
相关的问题:PHP: What does pcntl_fork() really do?
过程控制不应该在Web服务器环境中启用,如果任何过程控制功能在Web服务器中使用可能会发生意想不到的结果环境。
答
寻找用户贡献的高管指出,它看起来像你可以使用它,请查看:
http://de3.php.net/manual/en/function.exec.php#86329
<?php function execInBackground($cmd) { if (substr(php_uname(), 0, 7) == "Windows"){ pclose(popen("start /B ". $cmd, "r")); } else { exec($cmd . " > /dev/null &"); } } ?>
这将执行$ cmd在 背景(没有cmd窗口)没有PHP 等待它t o完成,在Windows和Unix上均为 。
答
$pids = array();
foreach ($lotsOfItems as $item) {
if ($item->needsExtraHelp) {
$pid = pcntl_fork();
if ($pid == 0) {
// you're in the child
var_dump($item);
exit(0); // don't forget this one!!
} else if ($pid == -1) {
// failed to fork process
} else {
// you're in the parent
$pids[] = $pid;
}
}
usleep(100); // prevent CPU from peaking
foreach ($pids as $pid) {
pcntl_waitpid($pid, $exitcode, WNOHANG); // prevents zombie processes
}
}
你说“我不需要知道什么时候叉完整的”和你的代码说“并将它传递$项目”。你想获得输出吗? – Jonas 2010-12-07 20:00:29
PHP不起诉线程,你必须fork子进程,或者更好的方法是构建一个cron – RobertPitt 2010-12-07 20:07:06