Store php exec in a session variable

2019-08-30 22:33发布

问题:

Is is possible to store an exec' output into a session variable while its running to see it's current progress?

example:

index.php

<?php exec ("very large command to execute", $arrat, $_SESSION['output']); ?>

follow.php

<php echo $_SESSION['output']); ?>

So, when i run index.php i could close the page and navigate to follow.php and follow the output of the command live everytime i refresh the page.

回答1:

No, because exec waits for the spawned process to terminate before it returns. But it should be possible to do with proc_open because that function provides the outputs of the spawned process as streams and does not wait for it to terminate. So in broard terms you could do this:

  1. Use proc_open to spawn a process and redirect its output to pipes.
  2. Use stream_select inside some kind of loop to see if there is output to read; read it with the appropriate stream functions when there is.
  3. Whenever output is read, call session_start, write it to a session variable and call session_write_close. This is the standard "session lock dance" that allows your script to update session data without holding a lock on them the whole time.


回答2:

No, exec will run to completion and only then will store the result in session.

You should run a child process writing directly to a file and then read that file in your browser:

$path = tempnam(sys_get_temp_dir(), 'myscript');
$_SESSION['work_path'] = $path;

// Release session lock
session_write_close();

$process = proc_open(
    'my shell command',
    [
        0 => ['pipe', 'r'],
        1 => ['file', $path],
        2 => ['pipe', 'w'],
    ],
    $pipes
);

if (!is_resource($process)) {
    throw new Exception('Failed to start');
}

fclose($pipes[0]);
fclose($pipes[2]);
$return_value = proc_close($process);

In your follow.php you can then just output the current output:

echo file_get_contents($_SESSION['work_path']);


回答3:

No, You can't implement watching in this way.

I advise you to use file to populate status from index.php and read status from file in follow.php. As alternative for file you can use Memcache