【问题标题】:How to pass the content of a variable trough an external command in php?如何通过php中的外部命令传递变量的内容?
【发布时间】:2011-11-11 23:46:36
【问题描述】:

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

我想通过一个外部命令传递这个字符串,在本例中是一个 javascript 压缩器,并在 php 中捕获外部命令(压缩的 javascript)的输出,并将其分配给一个变量。

我知道 php 中有用于压缩 javascript 的类,但这只是一般问题的一个示例。

我们最初使用的是:

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

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

使用 escapeshellarg 转义可以解决这个问题,但由于操作系统对最大允许参数长度的限制,解决方案会中断更长的字符串。

我尝试使用popen("command" "w") 并写入命令 - 这可行,但命令的输出会默默地消失在空白中。

从概念上讲,我只想做相当于:

$newvar = external_command($oldvar);

【问题讨论】:

    标签: php popen passthru


    【解决方案1】:

    使用 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;
    }
    

    可能存在死锁问题:如果您发送的数据大于管道的组合大小,那么外部命令将阻塞,等待有人从它的标准输出中读取,而 php 被阻塞,等待标准输入为更多输入腾出空间。

    可能 PHP 以某种方式解决了这个问题,但如果您计划发送(或接收)比管道中容纳的更多数据,则值得测试一下。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-02
        • 2021-11-20
        • 2016-09-15
        • 2020-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多