我有一个程序,可以从 stdin
读取 JSON 请求,我想在 PHP 中调用该请求。
这就是我现在所拥有的
<?php
echo exec(
'echo \''.json_encode($_POST,JSON_NUMERIC_CHECK).'\' | '.
'program'
);
?>
这可行,但是有没有更直接的方法将 PHP 中的字符串放入 stdin
中?
也许类似于 pipe(json_encode($_POST,JSON_NUMERIC_CHECK),'program')
的内容?
在这种特殊情况下,我所拥有的可能没问题,但如果我需要管道二进制数据而不是 JSON,该怎么办?如果它太长而无法放入 shell 参数或包含单引号怎么办?
编辑:
已关注 miken32的建议,我用了proc_open()
像这样:
$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
参数似乎没有效果。有谁知道为什么吗?
最佳答案
您可以使用popen()
创建流程的管道:
<?php
$data = json_encode($_POST, JSON_NUMERIC_CHECK);
$p = popen("program", "w");
fwrite($p, $data . PHP_EOL);
$exit_code = pclose($p);
如果您需要从程序取回数据,事情会变得更加复杂,您需要使用 proc_open()
相反。
<?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";
}
关于php - 通过管道 $_POST 到外部命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53509311/