Guzzle项目中的PSR-7标准实现详解
guzzle Guzzle, an extensible PHP HTTP client 项目地址: https://gitcode.com/gh_mirrors/gu/guzzle
什么是PSR-7
PSR-7是PHP标准推荐规范中关于HTTP消息接口的定义,它规定了HTTP请求和响应消息的标准接口。Guzzle作为PHP中最流行的HTTP客户端之一,全面实现了PSR-7标准,这使得Guzzle能够与其他遵循PSR-7标准的库无缝协作。
消息基础
在Guzzle中,HTTP请求和响应都被视为"消息",它们都包含以下几个基本部分:
- 起始行(请求行或状态行)
- 头部集合
- 消息体
创建请求对象
use GuzzleHttp\Psr7\Request;
// 最简单的GET请求
$request = new Request('GET', 'http://example.com');
// 带头部和消息体的PUT请求
$headers = ['Content-Type' => 'application/json'];
$body = '{"name":"John"}';
$request = new Request('PUT', 'http://example.com/user', $headers, $body);
创建响应对象
use GuzzleHttp\Psr7\Response;
// 默认响应(状态码200)
$response = new Response();
// 自定义响应
$response = new Response(
404,
['Content-Type' => 'text/html'],
'<h1>Not Found</h1>',
'1.1',
'Not Found'
);
头部处理
头部基本操作
Guzzle提供了多种方法来处理HTTP头部:
$request = new Request('GET', '/', [
'User-Agent' => 'MyApp/1.0',
'Accept' => 'application/json'
]);
// 检查头部是否存在
if ($request->hasHeader('Accept')) {
// 获取头部值(返回数组)
$accept = $request->getHeader('Accept');
// 获取逗号分隔的头部字符串
$acceptLine = $request->getHeaderLine('Accept');
}
// 遍历所有头部
foreach ($request->getHeaders() as $name => $values) {
echo "$name: " . implode(', ', $values) . "\n";
}
复杂头部解析
对于包含键值对的复杂头部(如Link头部),Guzzle提供了专门的解析方法:
use GuzzleHttp\Psr7;
$request = new Request('GET', '/', [
'Link' => '<http://example.com>; rel="next"; type="text/html"'
]);
$parsed = Psr7\Header::parse($request->getHeader('Link'));
/*
输出:
array(
0 => array(
0 => '<http://example.com>',
'rel' => 'next',
'type' => 'text/html'
)
)
*/
消息体处理
流式接口
Guzzle使用StreamInterface
处理消息体,这种方式可以高效处理大文件而不会耗尽内存:
$response = $client->request('GET', 'http://example.com/large-file');
// 获取流对象
$body = $response->getBody();
// 读取前1024字节
echo $body->read(1024);
// 将指针重置到开始位置
$body->rewind();
// 检查是否到达流末尾
if ($body->eof()) {
echo "已读取完毕";
}
流创建方法
Guzzle提供了灵活的方式来创建流:
use GuzzleHttp\Psr7\Utils;
// 从字符串创建
$stream = Utils::streamFor('string data');
// 从资源创建
$resource = fopen('path/to/file', 'r');
$stream = Utils::streamFor($resource);
// 从可调用对象创建
$stream = Utils::streamFor(function($size) {
return generateSomeData($size);
});
请求细节
HTTP方法
Guzzle支持所有标准HTTP方法,也支持自定义方法:
// 标准方法
$request = new Request('POST', 'http://example.com');
// 自定义方法
$request = new Request('PURGE', 'http://example.com/cache');
URI处理
Guzzle提供了完整的URI处理能力:
$uri = 'http://username:password@example.com:8080/path?query=string#fragment';
$request = new Request('GET', $uri);
// 获取URI各部分
echo $request->getUri()->getScheme(); // http
echo $request->getUri()->getHost(); // example.com
echo $request->getUri()->getPort(); // 8080
echo $request->getUri()->getPath(); // /path
echo $request->getUri()->getQuery(); // query=string
echo $request->getUri()->getFragment(); // fragment
响应处理
响应状态
$response = $client->request('GET', 'http://example.com');
echo $response->getStatusCode(); // 200
echo $response->getReasonPhrase(); // OK
echo $response->getProtocolVersion(); // 1.1
响应体处理
对于JSON响应,可以这样处理:
$response = $client->request('GET', 'http://example.com/api');
$data = json_decode($response->getBody(), true);
流的高级用法
流元数据
$stream = Utils::streamFor(fopen('file.txt', 'r'));
$metadata = $stream->getMetadata();
echo $metadata['uri']; // file.txt
var_export($stream->isReadable());
var_export($stream->isWritable());
var_export($stream->isSeekable());
流装饰器
Guzzle提供了多种流装饰器来扩展流的功能:
- LimitStream - 限制读取的字节数
- CachingStream - 缓存之前读取的字节
- InflateStream - 解压缩gzip或deflate编码的数据
- MultipartStream - 用于创建multipart/form-data消息体
use GuzzleHttp\Psr7;
// 限制流读取大小
$original = Psr7\Utils::streamFor(fopen('huge.txt', 'r'));
$limited = new Psr7\LimitStream($original, 1024); // 只读取前1024字节
最佳实践
- 处理大响应:使用流式处理避免内存问题
- 重用请求:可以修改请求对象并重复使用
- 流自动管理:Guzzle会自动处理大于2MB的流,将其存储在磁盘而非内存中
- 异常处理:始终处理可能发生的网络异常
通过深入理解Guzzle的PSR-7实现,开发者可以构建出更高效、更可靠的HTTP客户端应用。Guzzle对PSR-7标准的完整支持也使得它能够与现代PHP生态系统中的其他组件良好协作。
guzzle Guzzle, an extensible PHP HTTP client 项目地址: https://gitcode.com/gh_mirrors/gu/guzzle
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考