【问题标题】:Grab results from a php exec() while the command is still running?在命令仍在运行时从 php exec() 获取结果?
【发布时间】:2011-10-09 11:51:07
【问题描述】:

当我像这样从 PHP 运行 exec 时:

$result = exec('command');

由此产生的结果将存储在$result。但在我目前的情况下,我的命令可能需要几分钟并在运行时输出结果。有没有办法在运行时获得输出?我知道passthru方法会将结果输出到浏览器,但我其实是直接想要的。

【问题讨论】:

  • 用 CGI 代替 PHP,可以吗?

标签: php exec


【解决方案1】:

你应该看看proc_open

在使输出流成为非阻塞(使用stream_set_blocking)后,您可以随时读取它,而不会阻塞您的 PHP 代码。

-编辑- 如果你使用

$result = exec('command > /path/to/file &');

它将在后台运行,您可以在 /path/to/file 中读取输出

【讨论】:

    【解决方案2】:

    也许不是最好的方法(但对我有用):

    <?php
    
    $cmd = "ping 127.0.0.1 -c 5"; //example command
    
    $descriptorspec = array(
        0 => array("pipe", "r"), 
        1 => array("pipe", "w"), 
        2 => array("pipe", "a")
    );
    
    $pipes = array();
    
    $process = proc_open($cmd, $descriptorspec, $pipes, null, null);
    
    echo "Start process:\n";
    
    $str = "";
    
    if(is_resource($process)) {
        do {
            $curStr = fgets($pipes[1]);  //will wait for a end of line
            echo $curStr;
            $str .= $curStr;
    
            $arr = proc_get_status($process);
    
        }while($arr['running']);
    }else{
        echo "Unable to start process\n";
    }
    
    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($process);
    
    echo "\n\n\nDone\n";
    
    echo "Result is:\n----\n".$str."\n----\n";
    
    ?>
    

    【讨论】:

      【解决方案3】:

      指定第二个参数

      exec('command', $result);
      

      如果输出参数存在,那么指定的数组将是 填充命令的每一行输出。尾随 此数组中不包含空格,例如 \n。请注意,如果 数组已经包含一些元素, exec() 将追加到 数组的末尾。如果您不希望函数附加元素, 在将数组传递给 exec() 之前调用数组上的 unset()。

      【讨论】:

      • 谢谢,但据我了解,这仍然需要 exec 完全完成才能获得输出。我特别希望在命令运行时获取输出,以便更新进度条。
      • @Zenox:啊。在这种情况下,这是不可能的。 PHP 不是异步的
      【解决方案4】:

      结合使用passthru()output buffering 或许可以实现您所需要的。不过不确定。

      【讨论】:

        【解决方案5】:

        无论对谁有帮助,我都使用了 Eddie 的答案并根据我的目的对其进行了修改(输出 MySQL 转储文件而不会使服务器的 RAM 泛滥)

        $dumpCommand = "mysqldump --skip-lock-tables -u $dbuser -p$dbpasswd $dbname";
        $dumpFileName = 'backup_'.$dbname.'-'.date('Ymd-Hi').'.sql';
        
        $descriptorSpec = array(
            0 => array("pipe", "r"), 
            1 => array("pipe", "w"), 
            2 => array("pipe", "a")
        );
        
        $pipes = array();
        
        $process = proc_open($dumpCommand, $descriptorSpec, $pipes, null, null);
        
        if(!is_resource($process)) {
            die('Unable to start process');
        }
        
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.$dumpFileName.'"');
        
        do {
            echo fgets($pipes[1]); // Will wait for EOL
            $arrStatus = proc_get_status($process);
        } while($arrStatus['running']);
        
        fclose($pipes[0]);
        fclose($pipes[1]);
        fclose($pipes[2]);
        proc_close($process);
        

        【讨论】:

          猜你喜欢
          • 2019-02-18
          • 1970-01-01
          • 2014-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-21
          • 2011-04-18
          • 2015-09-30
          相关资源
          最近更新 更多