3

The PHP built-in webserver does not seem to handle shell_exec()ing background processes properly; the request hangs until the background process is complete, even if it's explicitly placed in the background with &.

Example:

$ ls
runit.php
$ cat runit.php 
<?php
echo "Here we are\n";
shell_exec("sleep 5 &");
echo "and the command is done\n";
?>
$ php -S localhost:7891
PHP 5.5.9-1ubuntu4.9 Development Server started at Mon May 18 19:20:12 2015
Listening on http://localhost:7891
Press Ctrl-C to quit.

and then in another shell:

$ GET http://localhost:7891/runit.php
(...waits five seconds...)
Here we are
and the command is done

This shouldn't happen, and indeed doesn't if one uses a production-grade webserver. Is there any way to work around it?

(Note: this is not a flushing problem. Adding flush() after the first echo doesn't make it happen, and the request still hangs until the background process is complete.)

2 Answers 2

1

This is acknowledged as a bug by PHP, but won't be fixed in the built-in webserver. However, the bug report does also suggest a workaround; set a correct Content-Length on the response, and then the receiving browser will close the request at the client end after receiving that much data, thus working around the problem.

Sign up to request clarification or add additional context in comments.

Comments

-1

your options are:

1) Use separate thread to run your processes

<?php 
for ($i = 1; $i <= 5; ++$i) { 
        $pid = pcntl_fork(); 

        if (!$pid) { 
            sleep(1); 
            print "In child $i\n"; 
            exit($i); 
        } 
    } 

    while (pcntl_waitpid(0, $status) != -1) { 
        $status = pcntl_wexitstatus($status); 
        echo "Child $status completed\n"; 
    } 
?>

2) you can append '> /dev/null 2>/dev/null &' at the end of your shell exec, which will get rid of all output too, but it will run the command. making it look like

shell_exec('sleep 5 > /dev/null 2>/dev/null &');

1 Comment

Sadly, neither approach works. What I want is the PHP request to return immediately, and the background process to carry on running after the PHP request has returned. Redirecting stdout and stderr to /dev/null doesn't change anything (the request still takes 5 seconds to complete), and fork()ing doesn't either, I'm afraid. They may work in a "proper" web server, but not in the PHP built-in server.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.