我有一个包含长字符串的变量。 (特别是它包含几千字节的javascript代码)
我希望通过外部命令传递此字符串,在本例中为javascript-compressor,并在php中捕获外部命令(压缩的javascript)的输出,并将其分配给变量。
我知道有一些用于在php中压缩javascript的类,但这只是一个普遍问题的一个例子。
最初我们使用过:
$newvar = passthru("echo $oldvar | compressor");
这适用于小字符串,但不安全。 (如果oldvar包含对shell有特殊含义的字符,则可能发生任何事情)
使用escapeshellarg进行转义修复,但由于最大允许参数长度的操作系统限制,解决方案会因较长的字符串而中断。
我尝试使用popen("command" "w")
并写入命令 - 这是有效的,但命令的输出会无声地消失在虚空中。
从概念上讲,我只想做相同的事情:
$newvar = external_command($oldvar);
答案 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以某种方式解决了这个问题,但是如果你打算发送(或接收)比管道中更多的数据,那么值得测试一下。