【问题标题】:PHP I/O consolePHP I/O 控制台
【发布时间】:2014-08-23 18:35:06
【问题描述】:

我有一个可以在控制台中运行的应用程序(通常的 .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 体系结构不将文件描述符编号与低级句柄相关联,因此子进程(还)没有访问这些句柄的方法。标准输入、标准输出和标准错误按预期工作。

所以command>&3 很容易,但我无法为 I/O 定义新的(我自己的)句柄。

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

我已经仔细检查了 Internet 上的大量资源,但没有得到关于 PHP 的正常答案。它是 Java 的基础,例如 C/C++,但不是 PHP。

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

【问题讨论】:

    标签: php io console


    【解决方案1】:

    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 的文档和 cmets。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 2011-06-20
      • 2012-06-02
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多