PSR-7 消息实现简介
PSR-7 是 PHP 标准推荐规范之一,主要用于定义 HTTP 消息接口。这个实现库不仅包含了完整的 PSR-7 消息接口,还提供了多种流装饰器和一些实用的功能,比如查询字符串解析。如果你正在与 HTTP 相关的 PHP 应用,这个库绝对值得一试。
流实现详解
这个库提供了多种流实现和流装饰器,帮助你更灵活地处理数据流。下面我们来看看一些常见的流实现。
AppendStream:多流拼接
AppendStream
允许你将多个流按顺序拼接在一起。比如,你可以将两个字符串流拼接成一个完整的句子:
use GuzzleHttp\Psr7;
$a = Psr7\Utils::streamFor('abc, ');
$b = Psr7\Utils::streamFor('123.');
$composed = new Psr7\AppendStream([$a, $b]);
$composed->addStream(Psr7\Utils::streamFor(' Above all listen to me'));
echo $composed; // 输出:abc, 123. Above all listen to me.
BufferStream:缓冲流
BufferStream
提供了一个缓冲流,允许你写入数据到缓冲区,并从缓冲区读取数据。当缓冲区超过设定的高水位标记时,写入操作会返回 false
,提示写入者需要放慢速度。
use GuzzleHttp\Psr7;
$buffer = new Psr7\BufferStream(1024);
CachingStream:缓存非可寻址流
CachingStream
用于在非可寻址流上实现回退操作。当你需要重新读取之前的数据时,这个流会将数据缓存到内存或磁盘中。
use GuzzleHttp\Psr7;
$original = Psr7\Utils::streamFor(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
DroppingStream:数据丢弃流
DroppingStream
在底层流的数据量超过设定值时,开始丢弃新写入的数据。
use GuzzleHttp\Psr7;
$stream = Psr7\Utils::streamFor();
$dropping = new Psr7\DroppingStream($stream, 10);
$dropping->write('01234567890123456789');
echo $stream; // 输出:0123456789
FnStream:函数式流
FnStream
允许你基于一组函数来组合流实现,非常适合在测试或扩展流时使用。
use GuzzleHttp\Psr7;
$stream = Psr7\Utils::streamFor('hi');
$fnStream = Psr7\FnStream::decorate($stream, [
'rewind' => function () use ($stream) {
echo 'About to rewind - ';
$stream->rewind();
echo 'rewound!';
}
]);
$fnStream->rewind(); // 输出:About to rewind - rewound!
InflateStream:解压缩流
InflateStream
使用 PHP 的 zlib.inflate
过滤器来解压缩 deflate
或 gzip
格式的内容。
LazyOpenStream:延迟打开文件流
LazyOpenStream
只在需要时才会打开文件进行读写操作,适合处理大文件。
use GuzzleHttp\Psr7;
$stream = new Psr7\LazyOpenStream('/path/to/file', 'r');
echo $stream->read(10); // 文件在需要时才会被打开
LimitStream:限制流大小
LimitStream
用于读取现有流的一部分数据,适合处理大文件的分块上传。
use GuzzleHttp\Psr7;
$original = Psr7\Utils::streamFor(fopen('/tmp/test.txt', 'r+'));
$stream = new Psr7\LimitStream($original, 1024, 2048);
echo $stream->getSize(); // 输出:1024
NoSeekStream:不可寻址流
NoSeekStream
包装一个流并禁止寻址操作。
use GuzzleHttp\Psr7;
$original = Psr7\Utils::streamFor('foo');
$noSeek = new Psr7\NoSeekStream($original);
echo $noSeek->read(3); // 输出:foo
PumpStream:回调数据流
PumpStream
通过 PHP 回调函数生成数据流,适合处理需要动态生成数据的场景。
实现流装饰器
通过 GuzzleHttp\Psr7\StreamDecoratorTrait
,你可以轻松创建自定义的流装饰器。比如,你可以在读取到流的末尾时执行特定的回调函数。
use Psr\Http\Message\StreamIntece;
use GuzzleHttp\Psr7\StreamDecoratorTrait;
class EofCallbackStream implements StreamIntece
{
use StreamDecoratorTrait;
private $callback;
public function __construct(StreamIntece $stream, callable $cb)
{
$this->stream = $stream;
$this->callback = $cb;
}
public function read($length)
{
$result = $this->stream->read($length);
if ($this->eof()) {
call_user_func($this->callback);
}
return $result;
}
}
PHP 流包装器
如果你需要将 PSR-7 流作为 PHP 流资源使用,可以使用 GuzzleHttp\Psr7\StreamWrapper
类。
use GuzzleHttp\Psr7\StreamWrapper;
$stream = GuzzleHttp\Psr7\Utils::streamFor('hello!');
$resource = StreamWrapper::getResource($stream);
echo fread($resource, 6); // 输出:hello!
静态 API
GuzzleHttp\Psr7
命名空间下还提供了多种静态方法,方便你处理 HTTP 消息。
GuzzleHttp\Psr7\Message::toString
将 HTTP 消息转换为字符串表示。
$request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com');
echo GuzzleHttp\Psr7\Message::toString($request);
GuzzleHttp\Psr7\Message::bodySummary
获取 HTTP 消息正文的简短摘要。
$summary = GuzzleHttp\Psr7\Message::bodySummary($response, 120);
通过这些功能,你可以更高效地处理 HTTP 请求和响应,提升效率。