用管道将$ _POST传递到外部命令 [英] Pipe $_POST to an external command

查看:108
本文介绍了用管道将$ _POST传递到外部命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆