2010-12-07 155 views
9

我正在创建一个将通过命令行运行的PHP脚本。作为这个脚本的一部分,有时候我可能需要产生/分叉一个可能需要很长时间才能完成的脚本。我不想阻止原始脚本完成。如果我使用JavaScript来完成这项工作,我可以在后台运行AJAX请求。这基本上是我在这里要做的。我不需要知道叉子何时完成,只是他们开始并完成自己。如何异步运行PHP脚本?

如何异步运行这些PHP脚本?

foreach ($lotsOfItems as $item) { 
    if ($item->needsExtraHelp) { 
     //start some asynchronous process here, and pass it $item 
    } 
} 
+0

你说“我不需要知道什么时候叉完整的”和你的代码说“并将它传递$项目”。你想获得输出吗? – Jonas 2010-12-07 20:00:29

+0

PHP不起诉线程,你必须fork子进程,或者更好的方法是构建一个cron – RobertPitt 2010-12-07 20:07:06

回答

2
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://www.php.net/manual/en/intro.pcntl.php

2

寻找用户贡献的高管指出,它看起来像你可以使用它,请查看:

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上均为 。

3
$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 
    } 
}