我是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;
}
替换输入或输出很容易,但我想同时替换两者。当我找到解决方案时,我会发布它。
最好的方法是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读取,请执行
$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,检查状态100000次,而最佳代码只检查一次。。我确信有一种奇特的方法可以让php休眠,直到进程通过一些回调/信号结束,也许是通过stream_select,但我还没有解决它。(如果有人有解决方案,请告诉我!)
--阅读更多http://php.net/manual/en/book.exec.php