用管道将$ _POST传递到外部命令 [英] Pipe $_POST to an external command
问题描述
我有一个程序可以从stdin
读取JSON请求,我想在PHP中调用它.
这就是我现在所拥有的
I have a program that reads a JSON request from stdin
, which I want to call in PHP.
Here's what I have right now
<?php
echo exec(
'echo \''.json_encode($_POST,JSON_NUMERIC_CHECK).'\' | '.
'program'
);
?>
这可行,但是有没有更直接的方法在stdin
中的PHP中放置字符串?
可能与pipe(json_encode($_POST,JSON_NUMERIC_CHECK),'program')
相似吗?
This works, but is there a more direct way to put a string in PHP in stdin
?
Something along the lines of pipe(json_encode($_POST,JSON_NUMERIC_CHECK),'program')
maybe?
在这种情况下,我所拥有的可能很好,但是如果我需要代替二进制数据而不是JSON,该怎么办?如果太长而无法放入shell参数或包含单引号怎么办?
What I have may be fine in this particular case, but what if instead of JSON, I'll need to pipe binary data? What if it's too long to fit into a shell argument, or contains single quotes?
修改:
按照 miken32 的建议,我使用了
Following miken32's suggestion, I used proc_open()
like this:
$proc = proc_open(
'LD_LIBRARY_PATH=/foo/bar/lib program args',
array(0 => array('pipe','r'), 1 => array('pipe','w')),
$pipes,
NULL
//, array('LD_LIBRARY_PATH','/foo/bar/lib')
);
if (is_resource($proc)) {
fwrite($pipes[0],json_encode($_POST,JSON_NUMERIC_CHECK));
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($proc);
}
?>
但是我必须在命令参数中添加LD_LIBRARY_PATH=/foo/bar/lib
. $env
参数似乎无效.有人知道为什么吗?
But I had to add LD_LIBRARY_PATH=/foo/bar/lib
to the command argument. The $env
argument seems to have no effect. Does anyone know why?
推荐答案
您可以使用 popen()
创建到流程的管道:
You can use popen()
to create a pipeline to a process:
<?php
$data = json_encode($_POST, JSON_NUMERIC_CHECK);
$p = popen("program", "w");
fwrite($p, $data . PHP_EOL);
$exit_code = pclose($p);
如果您需要从程序中获取数据,则会涉及更多事情,并且需要使用 proc_open()
代替.
If you need to get data back from the program, things get more involved and you need to use proc_open()
instead.
<?php
$data = json_encode($_POST, JSON_NUMERIC_CHECK);
$fds = [
0=>["pipe", "r"], // STDIN
1=>["pipe", "w"], // STDOUT
2=>["pipe", "w"], // STDERR
];
$dir = "/path/to/working/directory";
$env = [
"PATH" => "/usr/local/foo/bin:/usr/local/bin:/usr/bin",
"LD_LIBRARY_PATH" => "/usr/local/foo/lib/",
];
$p = proc_open("program", $fds, $pipes, $dir, $env);
fwrite($pipes[0], $data . PHP_EOL);
fclose($pipes[0]);
$return = stream_get_contents($pipes[1]);
$err = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
$exit_code = proc_close($p);
if ($exit_code == 0) {
// successful return
echo $return;
} else {
// error
echo "ERR: $err";
}
这篇关于用管道将$ _POST传递到外部命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!