Guzzle和PSR-7

Guzzle利用PSR-7作为HTTP消息接口。这使得Guzzle可以与任何其他利用PSR-7消息接口的库一起工作。

Guzzle是一个HTTP客户端,它向服务器发送HTTP请求并接收HTTP响应。请求和响应都被称为消息。

Guzzle依靠guzzlehttp/psr7 Composer软件包来实现PSR-7的消息。

你可以使用GuzzleHttp\Psr7\Request 类创建一个请求。

use GuzzleHttp\Psr7\Request;

$request = new Request('GET', 'http://httpbin.org/get');

// You can provide other optional constructor arguments.
$headers = ['X-Foo' => 'Bar'];
$body = 'hello!';
$request = new Request('PUT', 'http://httpbin.org/put', $headers, $body);

你可以使用GuzzleHttp\Psr7\Response 类来创建一个响应。

use GuzzleHttp\Psr7\Response;

// The constructor requires no arguments.
$response = new Response();
echo $response->getStatusCode(); // 200
echo $response->getProtocolVersion(); // 1.1

// You can supply any number of optional arguments.
$status = 200;
$headers = ['X-Foo' => 'Bar'];
$body = 'hello!';
$protocol = '1.1';
$response = new Response($status, $headers, $body, $protocol);

标题

请求和响应信息都包含HTTP头。

访问标题

你可以使用hasHeader()方法检查一个请求或响应是否有一个特定的头。

use GuzzleHttp\Psr7;

$request = new Psr7\Request('GET', '/', ['X-Foo' => 'bar']);

if ($request->hasHeader('X-Foo')) {
    echo 'It is there';
}

你可以使用getHeader()检索所有头的值,作为一个字符串的数组。

$request->getHeader('X-Foo'); // ['bar']

// Retrieving a missing header returns an empty array.
$request->getHeader('X-Bar'); // []

你可以使用getHeaders()方法来遍历一个消息的标题。

foreach ($request->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values) . "\r\n";
}

复杂的标题

一些头信息包含额外的键值对信息。例如,Link头信息包含一个链接和几个键值对。

<http://foo.com>; rel="thing"; type="image/jpeg"

Guzzle提供了一个方便的功能,可以用来解析这些类型的头文件。

use GuzzleHttp\Psr7;

$request = new Psr7\Request('GET', '/', [
    'Link' => '<http:/.../front.jpeg>; rel="front"; type="image/jpeg"'
]);

$parsed = Psr7\Header::parse($request->getHeader('Link'));
var_export($parsed);

将输出。

array (
  0 =>
  array (
    0 => '<http:/.../front.jpeg>',
    'rel' => 'front',
    'type' => 'image/jpeg',
  ),
)

其结果包含一个键值对的哈希值。没有键值的标题值 (即链接)的标题值按数字索引,而形成键值对的标题部分则作为键值对加入。 值对的标题部分则作为一个键值对被添加。

身体

请求和响应信息都可以包含一个主体。

你可以使用getBody()方法来检索一个消息的正文。

$response = GuzzleHttp\get('http://httpbin.org/get');
echo $response->getBody();
// JSON string: { ... }

在请求和响应对象中使用的主体是一个 Psr\Http\MessageStreamInterface 。这个流被用于 上传数据和下载数据。默认情况下,Guzzle会把信息的主体存储在一个使用PHP的流中。 消息的主体,并使用PHP的临时流。当正文的大小 超过2MB时,流会自动切换到将数据存储在磁盘上而不是内存中。 而不是内存中(保护你的应用程序不被内存耗尽)。

为一个消息创建主体的最简单方法是使用streamFor GuzzleHttp\Psr7Utils 类中的方法 -- Utils::streamFor 。这个方法接受字符串、资源。 呼叫器、迭代器、其他流媒体,并返回一个流媒体的实例。 Psr\Http\Message\StreamInterface

请求或响应的主体可以被转换为一个字符串,或者你可以根据需要从流中读写字节。

use GuzzleHttp\Stream\Stream;
$response = $client->request('GET', 'http://httpbin.org/get');

echo $response->getBody()->read(4);
echo $response->getBody()->read(4);
echo $response->getBody()->read(1024);
var_export($response->eof());

请求

请求是由客户端发送给服务器的。请求包括要应用于资源的方法 要应用于一个资源的方法、资源的标识符和要使用的协议版本。 版本。

请求方法

当创建一个请求时,你应该提供你希望执行的HTTP方法。 来执行。你可以指定任何你想要的方法,包括一个可能不属于RFC 7231的自定义方法 可能不是RFC 7231的一部分(如 "MOVE")。

// Create a request using a completely custom HTTP method
$request = new \GuzzleHttp\Psr7\Request('MOVE', 'http://httpbin.org/move');

echo $request->getMethod();
// MOVE

你可以在客户端使用与你希望使用的HTTP方法相对应的方法来创建和发送一个请求。

争取
$client->get('http://httpbin.org/get', [/** 选项 **/])
帖文
$client->post('http://httpbin.org/post', [/** 选项 **/])
负责人
$client->head('http://httpbin.org/get', [/** 选项 **/])
递交
$client->put('http://httpbin.org/put', [/** 选项 **/])
DELETE
$client->delete('http://httpbin.org/delete', [/** options **/])
选择
$client->options('http://httpbin.org/get', [/** options **/])
补丁
$client->patch('http://httpbin.org/put', [/** 选项 **/])

比如说。

$response = $client->patch('http://httpbin.org/patch', ['body' => 'content']);

请求URI

请求URI由一个Psr\HttpMessage\UriInterface 对象表示。 Guzzle提供了这个接口的一个实现,使用的是 GuzzleHttp\Psr7\Uri 类来实现这个接口。

当创建一个请求时,你可以将URI作为一个字符串或Psr\HttpMessage\UriInterface的实例提供。

$response = $client->request('GET', 'http://httpbin.org/get?q=foo');

方案

请求的方案 指定了发送请求时要使用的协议。当使用Guzzle时,该 方案可以被设置为 "http "或 "https"。

$request = new Request('GET', 'http://httpbin.org');
echo $request->getUri()->getScheme(); // http
echo $request->getUri(); // http://httpbin.org

主持人

使用请求所拥有的URI或通过访问Host头来访问主机。

$request = new Request('GET', 'http://httpbin.org');
echo $request->getUri()->getHost(); // httpbin.org
echo $request->getHeader('Host'); // httpbin.org

端口

使用 "http "或 "https "方案时,不需要端口。

$request = new Request('GET', 'http://httpbin.org:8080');
echo $request->getUri()->getPort(); // 8080
echo $request->getUri(); // http://httpbin.org:8080

路径

一个请求的路径可以通过URI对象访问。

$request = new Request('GET', 'http://httpbin.org/get');
echo $request->getUri()->getPath(); // /get

路径的内容将被自动过滤,以确保路径中只有 允许的字符出现在路径中。任何不允许的字符 的字符都将按照以下标准进行百分比编码 RFC 3986 section 3.3

查询字符串

一个请求的查询字符串可以使用请求所拥有的URI对象的getQuery()访问。

$request = new Request('GET', 'http://httpbin.org/?foo=bar');
echo $request->getUri()->getQuery(); // foo=bar

查询字符串的内容将被自动过滤以确保 只有允许的字符出现在查询字符串中。任何字符 的字符将根据以下规定进行百分比编码 RFC 3986 section 3.4

回复

响应是客户端在发送HTTP请求信息后从服务器收到的HTTP信息。

起始行

响应的起始行包含协议和协议版本、状态代码和原因短语。

$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'http://httpbin.org/get');

echo $response->getStatusCode(); // 200
echo $response->getReasonPhrase(); // OK
echo $response->getProtocolVersion(); // 1.1

身体

如前所述,你可以使用getBody()方法获取响应的主体。

$body = $response->getBody();
echo $body;
// Cast to a string: { ... }
$body->seek(0);
// Rewind the body
$body->read(1024);
// Read bytes of the body

流水

Guzzle使用PSR-7流对象来表示请求和响应信息体。 体。这些流对象允许你使用一个共同的接口来处理各种类型的数据。 使用一个共同的接口。

HTTP消息由起始行、头文件和正文组成。一个HTTP消息的主体可以非常小,也可以非常大。 消息的主体可以非常小,也可以非常大。试图用字符串来表示消息的主体 试图用一个字符串来表示一个消息的主体,很容易就会消耗比预期更多的内存,因为 体必须完全存储在内存中。试图将一个请求或响应的主体存储在内存中 试图将请求或响应的主体存储在内存中,将排除该实现的使用,使其不能 能够处理大的消息体。StreamInterface的使用是为了 以隐藏数据流从哪里读取或写入哪里的实现细节。 或写到哪里。

PSR-7 Psr\Http\MessageStreamInterface暴露了几个方法,使流可以有效地被读取、写入和遍历。

流使用三种方法暴露它们的能力。isReadable() isWritable(), 和 isSeekable() 。这些方法可以被流 合作者来确定一个流是否能够满足他们的要求。

每个流实例都有各种能力:它们可以是只读的。 它们可以是只读的、只写的、读写的,允许任意的随机访问(向前或向后寻找任何位置 向后寻找任何位置),或者只允许顺序访问(例如在 例如,在套接字或管道的情况下)。

Guzzle使用guzzlehttp/psr7 包来提供流支持。更多 关于使用流、创建流、将流转换为PHP 流资源,以及流装饰器的更多信息可以在 Guzzle PSR-7 文档

创建流

创建一个流的最好方法是使用GuzzleHttp\Psr7\Utils::streamFor 方法。这个方法接受字符串、从fopen()返回的资源。 一个实现__toString()的对象、迭代器、可调用程序以及__toString()的实例 Psr\Http\Message\StreamInterface的实例。

use GuzzleHttp\Psr7;

$stream = Psr7\Utils::streamFor('string data');
echo $stream;
// string data
echo $stream->read(3);
// str
echo $stream->getContents();
// ing data
var_export($stream->eof());
// true
var_export($stream->tell());
// 11

你可以从迭代器中创建流。迭代器可以产生任何数量的 字节。迭代器返回的任何多余的字节,如果不是由流消费者请求的 流消费者请求的多余字节将被缓冲,直到下一次读取。

use GuzzleHttp\Psr7;

$generator = function ($bytes) {
    for ($i = 0; $i < $bytes; $i++) {
        yield '.';
    }
};

$iter = $generator(1024);
$stream = Psr7\Utils::streamFor($iter);
echo $stream->read(3); // ...

元数据

流通过getMetadata()方法暴露了流元数据。这个 方法提供了你在调用PHP的 stream_get_meta_data()函数时。 并可以选择暴露其他自定义数据。

use GuzzleHttp\Psr7;

$resource = Psr7\Utils::tryFopen('/path/to/file', 'r');
$stream = Psr7\Utils::streamFor($resource);
echo $stream->getMetadata('uri');
// /path/to/file
var_export($stream->isReadable());
// true
var_export($stream->isWritable());
// false
var_export($stream->isSeekable());
// true

溪流装饰者

使用流装饰器为流添加自定义功能是非常简单的。 Guzzle提供了几个内置的装饰器来提供额外的流 功能。