如何异步运行PHP脚本?

时间:2010-12-07 19:49:42

标签: php asynchronous

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

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

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

3 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分:2)

int pcntl_fork ( void )

  

pcntl_fork()函数创建的子进程仅在其PID和PPID中与父进程不同。有关fork如何在系统上运行的具体细节,请参见系统的fork(2)手册页。

详细信息: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 :(得分:2)

查看用户在exec上提供的注释,看起来您可以使用它,请查看:

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   没有PHP的背景(没有cmd窗口)   两个都在等待它完成   Windows和Unix。