2e86c939
xu
“首次提交”
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
|
================
Guzzle and PSR-7
================
Guzzle utilizes PSR-7 as the HTTP message interface. This allows Guzzle to work
with any other library that utilizes PSR-7 message interfaces.
Guzzle is an HTTP client that sends HTTP requests to a server and receives HTTP
responses. Both requests and responses are referred to as messages.
Guzzle relies on the ``guzzlehttp/psr7`` Composer package for its message
implementation of PSR-7.
You can create a request using the ``GuzzleHttp\Psr7\Request`` class:
.. code-block:: php
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);
You can create a response using the ``GuzzleHttp\Psr7\Response`` class:
.. code-block:: php
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);
Headers
=======
Both request and response messages contain HTTP headers.
Accessing Headers
-----------------
You can check if a request or response has a specific header using the
``hasHeader()`` method.
.. code-block:: php
use GuzzleHttp\Psr7;
$request = new Psr7\Request('GET', '/', ['X-Foo' => 'bar']);
if ($request->hasHeader('X-Foo')) {
echo 'It is there';
}
You can retrieve all the header values as an array of strings using
``getHeader()``.
.. code-block:: php
$request->getHeader('X-Foo'); // ['bar']
// Retrieving a missing header returns an empty array.
$request->getHeader('X-Bar'); // []
You can iterate over the headers of a message using the ``getHeaders()``
method.
.. code-block:: php
foreach ($request->getHeaders() as $name => $values) {
echo $name . ': ' . implode(', ', $values) . "\r\n";
}
Complex Headers
---------------
Some headers contain additional key value pair information. For example, Link
headers contain a link and several key value pairs:
::
<http://foo.com>; rel="thing"; type="image/jpeg"
Guzzle provides a convenience feature that can be used to parse these types of
headers:
.. code-block:: php
use GuzzleHttp\Psr7;
$request = new Psr7\Request('GET', '/', [
'Link' => '<http:/.../front.jpeg>; rel="front"; type="image/jpeg"'
]);
$parsed = Psr7\parse_header($request->getHeader('Link'));
var_export($parsed);
Will output:
.. code-block:: php
array (
0 =>
array (
0 => '<http:/.../front.jpeg>',
'rel' => 'front',
'type' => 'image/jpeg',
),
)
The result contains a hash of key value pairs. Header values that have no key
(i.e., the link) are indexed numerically while headers parts that form a key
value pair are added as a key value pair.
Body
====
Both request and response messages can contain a body.
You can retrieve the body of a message using the ``getBody()`` method:
.. code-block:: php
$response = GuzzleHttp\get('http://httpbin.org/get');
echo $response->getBody();
// JSON string: { ... }
The body used in request and response objects is a
``Psr\Http\Message\StreamInterface``. This stream is used for both
uploading data and downloading data. Guzzle will, by default, store the body of
a message in a stream that uses PHP temp streams. When the size of the body
exceeds 2 MB, the stream will automatically switch to storing data on disk
rather than in memory (protecting your application from memory exhaustion).
The easiest way to create a body for a message is using the ``stream_for``
function from the ``GuzzleHttp\Psr7`` namespace --
``GuzzleHttp\Psr7\stream_for``. This function accepts strings, resources,
callables, iterators, other streamables, and returns an instance of
``Psr\Http\Message\StreamInterface``.
The body of a request or response can be cast to a string or you can read and
write bytes off of the stream as needed.
.. code-block:: php
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());
Requests
========
Requests are sent from a client to a server. Requests include the method to
be applied to a resource, the identifier of the resource, and the protocol
version to use.
Request Methods
---------------
When creating a request, you are expected to provide the HTTP method you wish
to perform. You can specify any method you'd like, including a custom method
that might not be part of RFC 7231 (like "MOVE").
.. code-block:: php
// Create a request using a completely custom HTTP method
$request = new \GuzzleHttp\Psr7\Request('MOVE', 'http://httpbin.org/move');
echo $request->getMethod();
// MOVE
You can create and send a request using methods on a client that map to the
HTTP method you wish to use.
:GET: ``$client->get('http://httpbin.org/get', [/** options **/])``
:POST: ``$client->post('http://httpbin.org/post', [/** options **/])``
:HEAD: ``$client->head('http://httpbin.org/get', [/** options **/])``
:PUT: ``$client->put('http://httpbin.org/put', [/** options **/])``
:DELETE: ``$client->delete('http://httpbin.org/delete', [/** options **/])``
:OPTIONS: ``$client->options('http://httpbin.org/get', [/** options **/])``
:PATCH: ``$client->patch('http://httpbin.org/put', [/** options **/])``
For example:
.. code-block:: php
$response = $client->patch('http://httpbin.org/patch', ['body' => 'content']);
Request URI
-----------
The request URI is represented by a ``Psr\Http\Message\UriInterface`` object.
Guzzle provides an implementation of this interface using the
``GuzzleHttp\Psr7\Uri`` class.
When creating a request, you can provide the URI as a string or an instance of
``Psr\Http\Message\UriInterface``.
.. code-block:: php
$response = $client->request('GET', 'http://httpbin.org/get?q=foo');
Scheme
------
The `scheme <http://tools.ietf.org/html/rfc3986#section-3.1>`_ of a request
specifies the protocol to use when sending the request. When using Guzzle, the
scheme can be set to "http" or "https".
.. code-block:: php
$request = new Request('GET', 'http://httpbin.org');
echo $request->getUri()->getScheme(); // http
echo $request->getUri(); // http://httpbin.org
Host
----
The host is accessible using the URI owned by the request or by accessing the
Host header.
.. code-block:: php
$request = new Request('GET', 'http://httpbin.org');
echo $request->getUri()->getHost(); // httpbin.org
echo $request->getHeader('Host'); // httpbin.org
Port
----
No port is necessary when using the "http" or "https" schemes.
.. code-block:: php
$request = new Request('GET', 'http://httpbin.org:8080');
echo $request->getUri()->getPort(); // 8080
echo $request->getUri(); // http://httpbin.org:8080
Path
----
The path of a request is accessible via the URI object.
.. code-block:: php
$request = new Request('GET', 'http://httpbin.org/get');
echo $request->getUri()->getPath(); // /get
The contents of the path will be automatically filtered to ensure that only
allowed characters are present in the path. Any characters that are not allowed
in the path will be percent-encoded according to
`RFC 3986 section 3.3 <https://tools.ietf.org/html/rfc3986#section-3.3>`_
Query string
------------
The query string of a request can be accessed using the ``getQuery()`` of the
URI object owned by the request.
.. code-block:: php
$request = new Request('GET', 'http://httpbin.org/?foo=bar');
echo $request->getUri()->getQuery(); // foo=bar
The contents of the query string will be automatically filtered to ensure that
only allowed characters are present in the query string. Any characters that
are not allowed in the query string will be percent-encoded according to
`RFC 3986 section 3.4 <https://tools.ietf.org/html/rfc3986#section-3.4>`_
Responses
=========
Responses are the HTTP messages a client receives from a server after sending
an HTTP request message.
Start-Line
----------
The start-line of a response contains the protocol and protocol version,
status code, and reason phrase.
.. code-block:: php
$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
Body
----
As described earlier, you can get the body of a response using the
``getBody()`` method.
.. code-block:: php
$body = $response->getBody();
echo $body;
// Cast to a string: { ... }
$body->seek(0);
// Rewind the body
$body->read(1024);
// Read bytes of the body
Streams
=======
Guzzle uses PSR-7 stream objects to represent request and response message
bodies. These stream objects allow you to work with various types of data all
using a common interface.
HTTP messages consist of a start-line, headers, and a body. The body of an HTTP
message can be very small or extremely large. Attempting to represent the body
of a message as a string can easily consume more memory than intended because
the body must be stored completely in memory. Attempting to store the body of a
request or response in memory would preclude the use of that implementation from
being able to work with large message bodies. The StreamInterface is used in
order to hide the implementation details of where a stream of data is read from
or written to.
The PSR-7 ``Psr\Http\Message\StreamInterface`` exposes several methods
that enable streams to be read from, written to, and traversed effectively.
Streams expose their capabilities using three methods: ``isReadable()``,
``isWritable()``, and ``isSeekable()``. These methods can be used by stream
collaborators to determine if a stream is capable of their requirements.
Each stream instance has various capabilities: they can be read-only,
write-only, read-write, allow arbitrary random access (seeking forwards or
backwards to any location), or only allow sequential access (for example in the
case of a socket or pipe).
Guzzle uses the ``guzzlehttp/psr7`` package to provide stream support. More
information on using streams, creating streams, converting streams to PHP
stream resource, and stream decorators can be found in the
`Guzzle PSR-7 documentation <https://github.com/guzzle/psr7/blob/master/README.md>`_.
Creating Streams
----------------
The best way to create a stream is using the ``GuzzleHttp\Psr7\stream_for``
function. This function accepts strings, resources returned from ``fopen()``,
an object that implements ``__toString()``, iterators, callables, and instances
of ``Psr\Http\Message\StreamInterface``.
.. code-block:: php
use GuzzleHttp\Psr7;
$stream = Psr7\stream_for('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
You can create streams from iterators. The iterator can yield any number of
bytes per iteration. Any excess bytes returned by the iterator that were not
requested by a stream consumer will be buffered until a subsequent read.
.. code-block:: php
use GuzzleHttp\Psr7;
$generator = function ($bytes) {
for ($i = 0; $i < $bytes; $i++) {
yield '.';
}
};
$iter = $generator(1024);
$stream = Psr7\stream_for($iter);
echo $stream->read(3); // ...
Metadata
--------
Streams expose stream metadata through the ``getMetadata()`` method. This
method provides the data you would retrieve when calling PHP's
`stream_get_meta_data() function <http://php.net/manual/en/function.stream-get-meta-data.php>`_,
and can optionally expose other custom data.
.. code-block:: php
use GuzzleHttp\Psr7;
$resource = fopen('/path/to/file', 'r');
$stream = Psr7\stream_for($resource);
echo $stream->getMetadata('uri');
// /path/to/file
var_export($stream->isReadable());
// true
var_export($stream->isWritable());
// false
var_export($stream->isSeekable());
// true
Stream Decorators
-----------------
Adding custom functionality to streams is very simple with stream decorators.
Guzzle provides several built-in decorators that provide additional stream
functionality.
- `AppendStream <https://github.com/guzzle/psr7#appendstream>`_
- `BufferStream <https://github.com/guzzle/psr7#bufferstream>`_
- `CachingStream <https://github.com/guzzle/psr7#cachingstream>`_
- `DroppingStream <https://github.com/guzzle/psr7#droppingstream>`_
- `FnStream <https://github.com/guzzle/psr7#fnstream>`_
- `InflateStream <https://github.com/guzzle/psr7#inflatestream>`_
- `LazyOpenStream <https://github.com/guzzle/psr7#lazyopenstream>`_
- `LimitStream <https://github.com/guzzle/psr7#limitstream>`_
- `NoSeekStream <https://github.com/guzzle/psr7#noseekstream>`_
- `PumpStream <https://github.com/guzzle/psr7#pumpstream>`_
|