本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
AWS SDK for PHP 版本 3 中的流
由于 集成了 Body
S3::PutObject 命令的 参数),字符串、PHP 流资源或 Psr\Http\Message\StreamInterface
的实例均可满足该命令。
警告
开发工具包会负责处理所有作为命令输入参数提供的原始 PHP 流资源。将代表您使用并关闭流。
如果您需要在开发工具包操作和代码之间共享流,请先将它包装在 GuzzleHttp\Psr7\Stream
的实例中,再作为参数包含在命令中。开发工具包会使用流,因此您的代码需要考虑流的内部游标的移动。Guzzle 流在被 PHP 的垃圾回收器销毁时会对底层流资源调用 fclose
,因此您无需自己关闭流。
流装饰器
Guzzle 提供多种流装饰器,可用于控制开发工具包和 Guzzle 与作为命令输入参数提供的流资源进行交互的方式。这些装饰器可修改处理程序在给定流上读取和搜寻的方式。以下是列表的一部分,在 GuzzleHttpPsr7 存储库
AppendStream
从多个流中依次读取。
use GuzzleHttp\Psr7; $a = Psr7\stream_for('abc, '); $b = Psr7\stream_for('123.'); $composed = new Psr7\AppendStream([$a, $b]); $composed->addStream(Psr7\stream_for(' Above all listen to me')); echo $composed(); // abc, 123. Above all listen to me.
CachingStream
允许在不可搜寻的流上搜寻之前读取的字节。如果由于需要倒回流导致未能传输不可搜寻的正文(例如重定向后),它非常有用。从远程流中读取的数据将缓存在 PHP 临时流中,这样上次读取的字节将首先缓存到内存中,然后再缓存到磁盘上。
use GuzzleHttp\Psr7; $original = Psr7\stream_for(fopen('http://www.google.com', 'r')); $stream = new Psr7\CachingStream($original); $stream->read(1024); echo $stream->tell(); // 1024 $stream->seek(0); echo $stream->tell(); // 0
InflateStream
使用 PHP 的 zlib.inflate 筛选条件来增加或减少使用 gzip 压缩的内容。
这个流装饰器会跳过给定流的前 10 个字节,以删除 gzip 标头,将提供的流转换为 PHP 流资源,然后附加 zlib.inflate 筛选器。然后该流将会转换回 Guzzle 流资源,用作 Guzzle 流。
LazyOpenStream
GuzzleHttp\Psr7\LazyOpenStream
仅在流中发生 I/O 操作后,再延时读取或写入已打开的文件。
use GuzzleHttp\Psr7; $stream = new Psr7\LazyOpenStream('/path/to/file', 'r'); // The file has not yet been opened... echo $stream->read(10); // The file is opened and read from only when needed.
LimitStream
用于读取现有流对象的子集或分片。如需将较大文件拆分为小块,以便分段发送(例如 Amazon S3 Multipart Upload API),那么它很有用。
use GuzzleHttp\Psr7; $original = Psr7\stream_for(fopen('/tmp/test.txt', 'r+')); echo $original->getSize(); // >>> 1048576 // Limit the size of the body to 1024 bytes and start reading from byte 2048 $stream = new Psr7\LimitStream($original, 1024, 2048); echo $stream->getSize(); // >>> 1024 echo $stream->tell(); // >>> 0
NoSeekStream
对流进行包装,不允许搜寻。
use GuzzleHttp\Psr7; $original = Psr7\stream_for('foo'); $noSeek = new Psr7\NoSeekStream($original); echo $noSeek->read(3); // foo var_export($noSeek->isSeekable()); // false $noSeek->seek(0); var_export($noSeek->read(3)); // NULL
PumpStream
提供只读流,从 PHP 可调用函数中提取数据。
如果调用提供的可调用函数,PumpStream 会向该可调用函数传递请求读取的数据量。可调用函数可以选择忽略此值,并返回少于请求或多于请求的字节。提供的可调用函数返回的所有额外数据将缓存于内部,直到使用 PumpStream 的 read() 函数耗尽。如果没有可读取的数据,提供的可调用函数必须返回 false。
实施流装饰器
由于有了 GuzzleHttp\Psr7\StreamDecoratorTrait,创建流装饰器变得非常容易。此特性通过代理底层流,提供实施 Psr\Http\Message\StreamInterface
的方法。只需 use
StreamDecoratorTrait
,并实施您的自定义方法。
例如,假设我们希望在每次读取流的最后一个字节时调用特定的函数。这可通过覆盖 read()
方法实施。
use Psr\Http\Message\StreamInterface; use GuzzleHttp\Psr7\StreamDecoratorTrait; class EofCallbackStream implements StreamInterface { use StreamDecoratorTrait; private $callback; public function __construct(StreamInterface $stream, callable $cb) { $this->stream = $stream; $this->callback = $cb; } public function read($length) { $result = $this->stream->read($length); // Invoke the callback when EOF is hit if ($this->eof()) { call_user_func($this->callback); } return $result; } }
此装饰器可添加到任何现有流中,使用方法与以下示例类似。
use GuzzleHttp\Psr7; $original = Psr7\stream_for('foo'); $eofStream = new EofCallbackStream($original, function () { echo 'EOF!'; }); $eofStream->read(2); $eofStream->read(1); // echoes "EOF!" $eofStream->seek(0); $eofStream->read(3); // echoes "EOF!"