Francesco Casula
Francesco Casula

Reputation: 27180

How to capture capture child process output in PHP

I need to capture the output of a child process in PHP to manipulate it.

I've two little scripts, parent.php and child.php

This is the code of parent.php

    $exe = $_SERVER['_'];
    $command = '/var/www/child.php';

    echo "\nSTART\n";

    $pid = pcntl_fork();

    ob_start();

    echo "\nHELLO\n";

    if ($pid == -1)
        exit("Could not fork");
    else if ($pid)
        pcntl_waitpid($pid, $status);
    else
    {
        $args = array
        (
            "arg1" => 'one',
            "arg2" => 'two',
            "arg3" => 'three'
        );

        pcntl_exec($exe, array($command), $args);
    }

    $content = ob_get_contents();
    ob_end_clean();

    echo "\nEND\n";

    echo $content . "\n";

And this is the code of child.php

    echo "\n\tHELLO FROM TEST\n";

    echo "\t"; var_dump($_SERVER['arg1']);
    echo "\t"; var_dump($_SERVER['arg2']);
    echo "\t"; var_dump($_SERVER['arg3']);

Now... this is my output:

START

    HELLO FROM TEST
    string(3) "one"
    string(3) "two"
    string(5) "three"

END

HELLO

But I need THIS output

START

END

HELLO

    HELLO FROM TEST
    string(3) "one"
    string(3) "two"
    string(5) "three"

Is this possible that the classic buffer workaround with ob_start() doesn't work??

Note: is not important the order of output, i need to capture it for manipulation purposes

Upvotes: 2

Views: 1721

Answers (1)

Francesco Casula
Francesco Casula

Reputation: 27180

I've found the solution.

You must use the proc_open() function that allow to you to work directly with the stream buffer:

echo "\nSTART\n";

$stream = null;

$descriptorspec = array(
   0 => array("pipe", "r"),
   1 => array("pipe", "w"),
   2 => array("file", "/tmp/error-output.txt", "a")
);

$cwd = '/tmp';
$env = array('some_option' => 'aeiou');

$process = proc_open('/usr/bin/php', $descriptorspec, $pipes, $cwd, $env);

if (is_resource($process))
{
    fwrite($pipes[0], '<?php echo "HELLO FROM TEST"; ?>'); // here directly the code of child.php
    fclose($pipes[0]);

    $stream = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    proc_close($process);
}

echo "\nEND\n";

echo "\n$stream\n";

Output is:

START

END

HELLO FROM TEST

Upvotes: 3

Related Questions