rkr/streams

PHP 基本流接口

0.0.1 2014-02-09 18:25 UTC

This package is auto-updated.

Last update: 2024-08-23 02:06:17 UTC


README

这个库正在开发中。

作为替代方案,请参阅: https://github.com/fzaninotto/Streamer

这是一个通用的、与框架无关的流接口方法。目标是提供一个抽象层,用于流提供者和流消费者。还提供了使用和预期行为的文档。还包括适当的异常和合规性测试。

流用于从资源中读取和写入。这里所说的流方法不是指Java 8等引入的方法。对于PHP而言,流的优势在于流在作为函数或方法参数传递时不会克隆其数据,当大量使用大字符串时,可以显著降低内存消耗。资源可以是任何能够输出或消费字节流的对象。

  • 设备
  • 文件
  • 网络
  • 管道
  • 虚拟资源
  • 转换器

为什么使用流而不是字符串?

流...

  • 保持字符集无关性
  • 可以像类一样按引用传递
  • 可以在某些情况下(几乎不消耗内存)进行序列化和反序列化。

由于抽象和多态,应用程序、服务或框架可以回退到相应的接口,因此可以处理任何形式的字节流。

这些接口是按照SOLID原则构建的,特别是接口隔离原则

  • 每个接口应只实现绝对必要的、可能存在的流类型所需的方法。
  • 任何流实现应仅需要实现基本功能。
  • 每个IoC感知组件应仅依赖于提供所需功能的外部接口。

例如,日志记录器只需要依赖于一个OutputStream。日志记录器不需要知道流的大小或当前光标位置。日志记录器不需要知道日志文件轮换或内存监控。这应该是外部组件的职责。因此,日志记录器可以写入任何可写流,而不必了解它实际上是什么类型的流。

在特定情况下,流可以是可序列化的。这是当流实现SerializableStream接口时的情况。内部,通常只序列化流的状态。在反序列化时,状态被恢复,并且流尝试到达流的最后位置。可序列化的内存流必须在序列化过程中将整个内容存储在某个地方。

字符集和数据类型

PHP没有像Java那样明确标识的字节数组支持。每个读写操作都是使用字符串完成的,这些字符串是(目前,在PHP 5.x、7.x和8.x中)8位字符数组。原则上,字符串是字节数组,但你不应该依赖它永远保持这种状态。流通常是字符集无关的。处理传入和传出数据的方式取决于特定的实现及其文档。该库(即将推出的)标准实现将提供对支持资源的简单8位访问。

概述

Inheritance

Stream 是许多其他类的基类(标记类)。其主要目的是提供连接或断开流的功能,并为类型提示提供一个基类型。

function handleStream(Stream $stream) {
	if($stream instanceof OutputStream) {
		// ...
	}
	if($stream instanceof InputStream) {
		// ...
	}
	throw new Exception('Unsupported stream type');
}

InfiniteInputStream

InfiniteInputStream 是一个只读流,根据定义没有结束。

示例

InputStream

InputStream 是一个有结束的只读流。

InputStream 发布以下方法

  • read:从当前位置读取 $length 个字节。如果当前位置加 $length 超过流的末尾,实际内容将只包含流末尾之前剩余的字节,并且光标将放置在那里。
  • isAtEnd:如果 true,则通过读取或查找操作已到达流的末尾。此方法不得抛出异常。

示例

  • 管道
  • 文件
  • 网络流

OutputStream

OutputStream 是一个只写流。它没有关于其大小或流中光标位置的信息。对于不需要 Stream 有其他功能(除了写入数据)的情况,OutputStream 是很好的选择。

示例

TruncatableStream

适用于可截断的资源。

SeekableStream

RandomAccessStream

VersatileStream 适用于如本地文件等完全可访问的资源。它扩展了 InputStreamOutputStreamSeekableStream。此接口应用于可读、可写和可查找的资源。

示例

  • 本地文件
  • 网络文件(ftp、sftp 等)
  • I/O 转换器(纯文本到 base64 及反之,加密和解密等)

版本控制

www.semver.org