PHP I / O控制台

时间:2014-08-23 18:35:06

标签: php io console

我有一个应用程序(通常的.exe文件),我可以在控制台中运行(例如作为守护进程)。它工作正常,输入/输出只是标准的STDIN / STDOUT,所以从控制台(windows或debian)没有问题。但我需要与php(我的PHP脚本)进行交互。

这也没问题,因为PHP中有很多'东西'可以做到这一点(proc_open,exec,系统,管道,字符串等等)。问题是应用程序在获取/接收数据期间必须工作(简单来说 - 这是一个守护进程),但上面的所有函数都在等待命令的执行结束和返回结果之后。

  

来自php.net

     

注意:        如果程序是使用此功能启动的,则为了使其在中继续运行        后台,程序的输出必须重定向到文件或另一个输出
       流。如果不这样做将导致PHP挂起,直到执行程序        结束。

众所周知如何使用> | &等重定向到另一个输入/输出(例如文件):

$last_line = system("myfile.exe>file2.txt", $retval);

即使作为守护进程也能正常工作。虽然我无法得到如何在模式中实现输入。 但是,我的主要问题是如何将标准输出重定向到非文件资源。 在php.net上写道:

  

Windows兼容性:超过2(stderr)的描述符可作为可继承句柄提供给子进程,但由于Windows体系结构不将文件描述符编号与低级句柄相关联,因此子进程(尚未)具有访问这些句柄的方法。 Stdin,stdout和stderr按预期工作。

所以它只是简单command>&3但我不能为I / O定义新的(我自己的)句柄。

所以问题是How to implement/handle input/output (to BOTH ways) for a daemon!!!

我在互联网上仔细检查了很多来源,但没有得到PHP的正常答案。它是Java的基础,例如,C / C ++而不是PHP。

也许有人帮助我 - 我会非常感激!

1 个答案:

答案 0 :(得分:0)

proc_*函数比您预期的更强大。你假设这些函数会阻塞是不正确的。

调用proc_open后,您可以将每个管道设置为非阻塞。这将导致您无需等待流程输入就可以使用fread,并尝试fwrite而无需等待流程接受它。

另外,我建议使用socket_select来确保您没有进入紧急循环,尝试读取/写入已执行的进程。当文件指针(在你的情况下是管道)准备好阅读或被写入时,选择结构将打破它的睡眠时间。

$descriptorspec = array(
  0 => array("pipe", "r"), // stdin
  1 => array("pipe", "w"), // stdout
  2 => array("file", "r") // stderr );

$process = proc_open('php', $descriptorspec, $pipes);

foreach($pipes as $pipe)
  stream_set_blocking($pipe, 0);

有关详细信息,请参阅socket_selectstream_set_blockingproc_open的文档和评论。