php - 通过管道 $_POST 到外部命令

标签 php post request pipe

我有一个程序,可以从 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/

相关文章:

PHP JSON file_put_contents 空白

javascript - 点击 skyscanner api 时获取纯文本响应

php - 是否可以使用 php 向另一台服务器发出请求并获得其响应?

javascript - Angular $http promise 和回调未触发

Graphite 烯模式中的Django http-request

node.js cookie 与 request.jar

php - 将数组内容放入表中

php - Laravel Vagrant 不工作 - Errno::EADDRNOTAVAIL

php - 与用户一起发送我自己的 $_POST 数据

php - Laravel:为什么我的 ajax 请求返回 "500 (Internal Server Error)"?