我是一名PHP初学者。我想调用一个外部Unix命令,将一些东西输入其中(例如,字符串和文件),并将结果显示在我的输出缓冲区(浏览器)中。
请考虑以下事项:
echo '<h1>stuff for my browser output window</h1>';
$fnmphp= '/tmp/someinputfile';
$sendtoprogram = "myheader: $fnmphp\n\n".get_file_contents($fnmphp);
popen2outputbuf("unixprogram < $sendtoprogram");
echo '<p>done</p>';
更好的解决方案是让PHP编写myheader(进入Unix程序),然后将文件管道$fnmphp
(进入Unix程序);并且unixprogram的输出会立即进入我的浏览器输出缓冲区。
我不认为PHP使用stdout
,因此我的Unix程序STDOUT
输出将进入浏览器。否则,如果我使用system()
,则会发生默认情况。我只能想到需要编写临时文件的解决方案。
我想我站在这里(德语成语;电线交叉)---这可能有一个明显的解决方案。
更新
这是我想要替换的完全不优雅但非常精确的解决方案:
function pipe2eqb( $text ) {
$whatever= '/tmp/whatever-'.time().'-'.$_SESSION['uid'];
$inf = "$whatever.in";
$outf= "$whatever.out";
assert(!file_exists($inf));
assert(!file_exists($outf));
file_put_contents($inf, $text);
assert(file_exists($inf));
system("unixprog < $inf > $outf");
$fo= file_get_contents($outf);
unlink($infilename);
unlink($outfilename);
return $fo;
}
很容易更换输入或输出,但我想更换两者。我想出来的时候会发布一个解决方案。
答案 0 :(得分:2)
最好这样做是proc_open函数系列
<?php
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$cwd = NULL;//'/tmp';
$env = NULL;//array();
$cmd='unixprog ';
$process = proc_open($cmd, $descriptorspec, $pipes, $cwd, $env);
assert(false!==$process);
现在,为了给unixprog提供参数,请点击
$cmd='unixprog --arg1='.escapeshellarg($arg1).' --arg2='.escapeshellarg($arg2);
与程序的stdin交谈,喜欢
assert(strlen($stdinmessage)===fwrite($pipes[0],$stdinmessage));
从进程的标准输出读取,喜欢
$stdout=file_get_contents($pipes[$1])
从流程的stderr读取,喜欢
$stderr=file_get_contents($pipes[$2])
检查程序是否已完成,请执行
$status=proc_get_status($process);
if($status['running']){echo 'child process is still running.';}
检查进程完成后的返回代码,
echo 'return code from child process: '.$status['exitcode'];
等待子进程完成,你可以做
while(proc_get_status($process)['running']){sleep(1);}
这是一种快速简便的方法,但它不是最佳选择。 tl; dr:它可能很慢或浪费cpu。长版: 有一些最佳的事件驱动方式来做到这一点,但我不知道该怎么做。想象必须运行程序10次,但程序在100毫秒内执行。这段代码会用10秒!而最佳代码只使用1秒。你可以使用usleep()微秒,但它仍然不是最优的,想象一下如果你每100微秒检查一次,但程序使用10秒执行:你会浪费cpu,检查状态100,000次,而最佳代码只会检查一次..我确定有一种奇特的方式让PHP睡眠,直到进程完成一些回调/信号,也许与stream_select,但我还没有解决它。 (如果有人有解决方案,请告诉我!)
了解详情