如何通过php中的外部命令传递变量的内容?

时间:2011-09-07 09:26:04

标签: php popen passthru

我有一个包含长字符串的变量。 (特别是它包含几千字节的javascript代码)

我希望通过外部命令传递此字符串,在本例中为javascript-compressor,并在php中捕获外部命令(压缩的javascript)的输出,并将其分配给变量。

我知道有一些用于在php中压缩javascript的类,但这只是一个普遍问题的一个例子。

最初我们使用过:

$newvar = passthru("echo $oldvar | compressor");

这适用于小字符串,但不安全。 (如果oldvar包含对shell有特殊含义的字符,则可能发生任何事情)

使用escapeshellarg进行转义修复,但由于最大允许参数长度的操作系统限制,解决方案会因较长的字符串而中断。

我尝试使用popen("command" "w")并写入命令 - 这是有效的,但命令的输出会无声地消失在虚空中。

从概念上讲,我只想做相同的事情:

$newvar = external_command($oldvar);

2 个答案:

答案 0 :(得分:2)

使用proc_open - 函数,您可以获取进程的stdout和stdin的句柄,从而将数据写入其中并读取结果。

答案 1 :(得分:0)

使用rumpels建议,我能够设置以下似乎运行良好的解决方案。发布此处是为了对任何对该问题感兴趣的人的利益。

public static function extFilter($command, $content){
    $fds = array(
        0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
        1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
        2 => array("pipe", "w")   // stderr is a pipe that the child will write to
    );
    $process = proc_open($command, $fds, $pipes, NULL, NULL);
    if (is_resource($process)) {
        fwrite($pipes[0], $content);
        fclose($pipes[0]);
        $stdout =  stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);
        $return_value = proc_close($process);
        // Do whatever you want to do with $stderr and the commands exit-code.
    } else {
        // Do whatever you want to do if the command fails to start
    }
    return $stdout;
}

可能存在死锁问题:如果您发送的数据大于管道的组合大小,那么外部命令将阻塞,等待某人从其stdout读取,而php被阻止,等待stdin到阅读以获得更多输入的空间。

可能PHP以某种方式解决了这个问题,但是如果你打算发送(或接收)比管道中更多的数据,那么值得测试一下。