PHP 的 "管道" 系统。

2.0.3 2019-12-07 20:43 UTC

This package is auto-updated.

Last update: 2024-09-04 15:51:53 UTC


README

PipeSys (俗称 Pipes)是一个用 PHP 实现的基本管道系统。

需求

  • PHP >= 5.6

工作原理

PipeSys 的工作方式是通过一个命令链,这些命令通过调度器连接在一起,以通过链式连接一个命令的输出到另一个命令的输入来产生管道的效果。调度器可以添加许多命令,并且所有命令都必须是 AbstractCommand 实例。

命令是特殊类,它们有一个 getCommand 方法,该方法应该返回一个生成器,即它应该包含 yield 语句。当命令想要读取时,应使用协程调用,如

$input = (yield new ReadIntent);

通过 yield 一个 ReadIntent 对象,命令知道它想要读取以继续。当有数据可供命令读取时,它将通过 send() 生成器方法发送。 $input 将拾取此发送的值,并生成器将继续。

当命令想要写入时,应该 yield 一个 OutputIntent,表示它打算输出某些内容。

yield new OutputIntent('Hello World!');

输出数据可以是任何你想要的内容,甚至可以发送到另一个通道,如 StdErr

yield new OutputIntent('Hello World!', IOConstants::IO_STDERR);

开始或结束的命令可以访问调度器的 stdinstdout,它们可能与系统的 stdinstdout 对应。(由 StdInStdOut 类提供。)

命令通过一个实现 ConnectorInterface 类的连接器连接,这允许你自定义和微调连接行为。提供了一个默认连接器 StandardConnector,它将第一个命令的输入连接到系统的 StdIn,最后一个命令的输出连接到系统的 StdOut,所有其他命令以链式方式连接它们的输出和输入(类似于 UNIX 管道),并且所有命令都连接到 StdErr 通道。

调度器使用协作式调度,因为 PHP 是单进程和多线程的,没有扩展就无法实现抢占式调度。

当 stdin 方法耗尽时,它应该返回一个 EOF 对象。《EOF》表示流(EOF = End Of File)已到达。读取命令很可能在接收到此信号后返回,因为它们通常在没有要读取的内容的情况下无法继续。

终止命令应 yield null 以通知系统它们不能再继续工作了。

示例代码

以下显示了简单命令链的示例。

ChattyYes 与 Unix 的 Yes 命令类似,除了输出 y 而不是 y 之外,它反复输出。

Yes
I
Am
Chatty

ChattyYes | head

上面的链路显示 ChattyYes 连接到 stdIn,其输出连接到 head,它将打印它接收到的前 10 行。

下面是相应的 PHP 代码

<?php

include 'vendor/autoload.php';

use ElvenSpellmaker\PipeSys as PS;
use ElvenSpellmaker\PipeSys\Command as Command;

$connector = new Command\StandardConnector;

$c = new PS\Scheduler($connector);
$c->addCommand(new Command\ChattyYes);
$c->addCommand(new Command\Head));
$c->run();

Output:
Yes
I
Am
Chatty
Yes
I
Am
Chatty
Yes
I
ChattyYes | grep "Chatty" | head

上面的链路显示 ChattyYes 连接到 stdIn,它输出到 grep,grep 正在查找短语 "Chatty",其输出连接到 head,它将打印它接收到的第一 10 行。

下面是相应的 PHP 代码

<?php

include 'vendor/autoload.php';

use ElvenSpellmaker\PipeSys as PS;
use ElvenSpellmaker\PipeSys\Command as Command;

$connector = new Command\StandardConnector;

$c = new PS\Scheduler($connector);
$c->addCommand(new Command\ChattyYes);
$c->addCommand(new Command\Grep('Chatty'));
$c->addCommand(new Command\Head));
$c->run();

Output:
Chatty
Chatty
Chatty
Chatty
Chatty
Chatty
Chatty
Chatty
Chatty
Chatty