How to run a PHP script asynchronously?

2019-04-21 09:01发布

I am creating a PHP script that will be run via the command line. As part of this script, there are times where I might need to spawn/fork a different script that could take a long time to complete. I don't want to block the original script from completing. If I were doing this with JavaScript, I could run AJAX requests in the background. That is essentially what I am trying to do here. I don't need to know when the forks complete, just that they start and complete themselves.

How can I run these PHP scripts asynchronously?

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

3条回答
戒情不戒烟
2楼-- · 2019-04-21 09:36

int pcntl_fork ( void )

The pcntl_fork() function creates a child process that differs from the parent process only in its PID and PPID. Please see your system's fork(2) man page for specific details as to how fork works on your system.

details : http://php.net/manual/en/function.pcntl-fork.php

related question : PHP: What does pcntl_fork() really do?

Process control should not be enabled within a web server environment and unexpected results may happen if any Process Control functions are used within a web server environment.

details: http://www.php.net/manual/en/intro.pcntl.php

查看更多
霸刀☆藐视天下
3楼-- · 2019-04-21 09:51
$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
    }
}
查看更多
倾城 Initia
4楼-- · 2019-04-21 09:51

Looking the user contributed notes on exec, it looks like you could use it, check out:

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 &");   
    } 
} 
?> 

This will execute $cmd in the background (no cmd window) without PHP waiting for it to finish, on both Windows and Unix.

查看更多
登录 后发表回答