amphp/byte-stream

一种用于简化非阻塞I/O工作的流抽象。

资助包维护!
amphp

安装: 68,047,944

依赖者: 90

建议者: 0

安全性: 0

星标: 364

观察者: 7

分叉: 31

开放问题: 2

v2.1.1 2024-02-17 04:49 UTC

README

AMPHP 是一个为 PHP 设计的事件驱动库集合,考虑了纤程和并发性。 amphp/byte-stream 特别提供了一个流抽象,以简化对各种字节流的操作。

安装

此包可以作为 Composer 依赖项安装。

composer require amphp/byte-stream

要求

此包需要 PHP 8.1 或更高版本。

用法

流是对有序字节序列的抽象。此包提供了基本接口 ReadableStreamWritableStream

注意 之前的版本使用了 InputStreamOutputStream 术语,但根据使用情况,这些术语可能会引起混淆。

ReadableStream

ReadableStream 提供了一个主要方法: read()。它返回一个 stringnullnull 表示流已结束。

以下示例展示了如何消耗一个 ReadableStream 并缓冲完整的流内容。

$stream = ...;
$buffer = "";

while (($chunk = $stream->read()) !== null) {
    $buffer .= $chunk;
}

// do something with $buffer

注意 可以使用 Amp\ByteStream\buffer($stream) 来代替,但在此处我们想演示手动消耗。

此包提供了一些基本实现,其他库可能提供更多实现,例如 amphp/socket

有效载荷

Payload 实现 ReadableStream 并同时提供一个 buffer() 方法来缓冲整个内容。这允许以块(流式传输)或一次性消耗整个消息。当对象被销毁时,流中剩余的所有数据将被自动消耗和丢弃。此类对于小型有效载荷或在需要处理之前需要整个流内容时非常有用。

缓冲

可以使用 buffer() 方法完成完整的可读流缓冲。

$payload = new Payload($inputStream);
$content = $payload->buffer();

流式传输

有时按块消耗有效载荷而不是首先完全缓冲它是有用或可能的,例如直接将大型 HTTP 响应体流式传输到磁盘。

while (null !== $chunk = $payload->read()) {
    // Use $chunk here, works just like any other ReadableStream
}

ReadableBuffer

ReadableBuffer 允许从一个已知的单个字符串块创建一个 ReadableStream。如果在已知完整的流内容时这很有帮助。

$stream = new ReadableBuffer("foobar");

它还允许通过将块传递为 null 或省略构造函数参数来创建没有任何块的字节流。

$stream = new ReadableBuffer;

// The stream ends immediately
assert(null === $stream->read());

ReadableIterableStream

ReadableIterableStream 允许将产生字符串的 iterable 转换为 ReadableStream

$inputStream = new Amp\ByteStream\ReadableIterableStream((function () {
    for ($i = 0; $i < 10; $i++) {
        Amp\delay(1);
        yield $emit(".");
    }
})());

ReadableResourceStream

此包使用 ReadableResourceStreamWritableResourceStream 抽象 PHP 的流资源。它们自动将传递的资源设置为非阻塞模式,并允许像其他任何 ReadableStream / WritableStream 一样读取和写入。它们还通过禁用在没有读取请求的情况下读取监视器来自动处理背压,并且只有当底层写缓冲区已满时才激活可写性监视器,这使得它们非常高效。

DecompressingReadableStream

此包实现了基于 Zlib 的压缩。可以使用 CompressingWritableStream 进行压缩,而 DecompressingReadableStream 用于解压缩。两者都可以简单地包装现有流以应用它们。两者在构造函数中接受 $encoding$options 参数。

$readableStream = new ReadableResourceStream(STDIN);
$decompressingReadableStream = new DecompressingReadableStream($readableStream, \ZLIB_ENCODING_GZIP);

while (null !== $chunk = $decompressingReadableStream) {
    print $chunk;
}

另请参阅: ./examples/gzip-decompress.php

可写流

可写流 提供了两种主要方法: write()end()

可写流::write

write() 将给定的字符串写入流。等待完成可以以底层流能写的速度写入,并且可能通过网络发送。只要写入缓冲区不满,TCP流将立即返回。

写入顺序始终得到保证,即使写入者在不等待完成的情况下发出另一个写入。

可写流::end

end() 将流标记为结束。TCP流可能会关闭底层流的写入,但不得关闭它。相反,所有资源都应该被释放,实际资源句柄应由PHP的垃圾回收过程关闭。

以下示例使用前面的示例从流中读取并将所有数据写入到 可写流

$readableStream = ...;
$writableStream = ...;
$buffer = "";

while (($chunk = $readableStream->read()) !== null) {
    $writableStream->write($chunk);
}

$writableStream->end();

注意 可以使用 Amp\ByteStream\pipe($readableStream, $writableStream) 代替,但我们希望在这里演示手动消费/写入。

此包提供了一些基本实现,其他库可能提供更多实现,例如 amphp/socket

可写资源流

此包使用 ReadableResourceStreamWritableResourceStream 抽象 PHP 的流资源。它们自动将传递的资源设置为非阻塞模式,并允许像其他任何 ReadableStream / WritableStream 一样读取和写入。它们还通过禁用在没有读取请求的情况下读取监视器来自动处理背压,并且只有当底层写缓冲区已满时才激活可写性监视器,这使得它们非常高效。

压缩可写流

此包实现了基于 Zlib 的压缩。可以使用 CompressingWritableStream 进行压缩,而 DecompressingReadableStream 用于解压缩。两者都可以简单地包装现有流以应用它们。两者在构造函数中接受 $encoding$options 参数。

$writableStream = new WritableResourceStream(STDOUT);
$compressedWritableStream = new CompressingWritableStream($writableStream, \ZLIB_ENCODING_GZIP);

for ($i = 0; $i < 100; $i++) {
    $compressedWritableStream->write(bin2hex(random_bytes(32));
}

$compressedWritableStream->end();

另请参阅: ./examples/gzip-compress.php

版本控制

amphp/byte-stream 遵循 semver 语义版本规范,就像所有的其他 amphp 包一样。

安全性

如果您发现任何与安全相关的问题,请通过电子邮件 [email protected] 反馈,而不是使用问题跟踪器。

许可协议

MIT 许可协议 (MIT)。有关更多信息,请参阅 LICENSE