Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run a PHP script asynchronously?

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
    }
}
like image 288
Andrew Avatar asked Dec 07 '10 19:12

Andrew


People also ask

Can PHP run asynchronously?

What Is Asynchronous PHP? Asynchronous PHP refers to PHP code that is written using the asynchronous model. In other words, asynchronous applications can multi-task. This is critical because traditionally, there's a lot of time when a CPU sits idle while a PHP application manages I/O tasks.

Is PHP asynchronous or synchronous?

PHP serves requests synchronously. It means that each line of code executes in the synchronous manner of the script. After getting the result from one line it executes next line or wait for the result before jumping to the execution of the next line of code.

Is PHP asynchronous by default?

When the recent PHP v/s Nodejs buzz came around, the one thing that always got the limelight was the fact that Nodejs implemented non-blocking (or asynchronous) I/O by default and PHP did not.


2 Answers

$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
    }
}
like image 129
netcoder Avatar answered Sep 28 '22 07:09

netcoder


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.

like image 21
Rob Avatar answered Sep 28 '22 07:09

Rob