Mercurial > hg > isophonics-drupal-site
comparison vendor/zendframework/zend-feed/doc/book/http-clients.md @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 # HTTP Clients and zend-feed | |
2 | |
3 Several operations in zend-feed's Reader subcomponent require an HTTP client: | |
4 | |
5 - importing a feed | |
6 - finding links in a feed | |
7 | |
8 In order to allow developers a choice in HTTP clients, the subcomponent defines | |
9 several interfaces and classes. Elsewhere in the documentation, we reference | |
10 where an HTTP client may be used; this document details what constitutes an HTTP | |
11 client and its behavior, and some of the concrete classes available within the | |
12 component for implementing this behavior. | |
13 | |
14 ## ClientInterface and HeaderAwareClientInterface | |
15 | |
16 First, we define two interfaces for clients, | |
17 `Zend\Feed\Reader\Http\ClientInterface` and `HeaderAwareClientInterface`: | |
18 | |
19 ```php | |
20 namespace Zend\Feed\Reader\Http; | |
21 | |
22 interface ClientInterface | |
23 { | |
24 /** | |
25 * Make a GET request to a given URL. | |
26 * | |
27 * @param string $url | |
28 * @return ResponseInterface | |
29 */ | |
30 public function get($url); | |
31 } | |
32 | |
33 interface HeaderAwareClientInterface extends ClientInterface | |
34 { | |
35 /** | |
36 * Make a GET request to a given URL. | |
37 * | |
38 * @param string $url | |
39 * @param array $headers | |
40 * @return ResponseInterface | |
41 */ | |
42 public function get($url, array $headers = []); | |
43 } | |
44 ``` | |
45 | |
46 The first is header-agnostic, and assumes that the client will simply perform an | |
47 HTTP GET request. The second allows providing headers to the client; typically, | |
48 these are used for HTTP caching headers. `$headers` must be in the following | |
49 structure: | |
50 | |
51 ```php | |
52 $headers = [ | |
53 'X-Header-Name' => [ | |
54 'header', | |
55 'values', | |
56 ], | |
57 ]; | |
58 ``` | |
59 | |
60 i.e., each key is a header name, and each value is an array of values for that | |
61 header. If the header represents only a single value, it should be an array with | |
62 that value: | |
63 | |
64 ```php | |
65 $headers = [ | |
66 'Accept' => [ 'application/rss+xml' ], | |
67 ]; | |
68 ``` | |
69 | |
70 A call to `get()` should yield a *response*. | |
71 | |
72 ## ResponseInterface and HeaderAwareResponseInterface | |
73 | |
74 Responses are modeled using `Zend\Feed\Reader\Http\ResponseInterface` and | |
75 `HeaderAwareResponseInterface`: | |
76 | |
77 ```php | |
78 namespace Zend\Feed\Reader\Http; | |
79 | |
80 class ResponseInterface | |
81 { | |
82 /** | |
83 * Retrieve the status code. | |
84 * | |
85 * @return int | |
86 */ | |
87 public function getStatusCode(); | |
88 | |
89 /** | |
90 * Retrieve the response body contents. | |
91 * | |
92 * @return string | |
93 */ | |
94 public function getBody(); | |
95 } | |
96 | |
97 class HeaderAwareResponseInterface extends ResponseInterface | |
98 { | |
99 /** | |
100 * Retrieve a named header line. | |
101 * | |
102 * Retrieve a header by name; all values MUST be concatenated to a single | |
103 * line. If no matching header is found, return the $default value. | |
104 * | |
105 * @param string $name | |
106 * @param null|string $default | |
107 * @return string | |
108 public function getHeaderLine($name, $default = null); | |
109 } | |
110 ``` | |
111 | |
112 Internally, `Reader` will typehint against `ClientInterface` for the bulk of | |
113 operations. In some cases, however, certain capabilities are only possible if | |
114 the response can provide headers (e.g., for caching); in such cases, it will | |
115 check the instance against `HeaderAwareResponseInterface`, and only call | |
116 `getHeaderLine()` if it matches. | |
117 | |
118 ## Response | |
119 | |
120 zend-feed ships with a generic `ResponseInterface` implementation, | |
121 `Zend\Feed\Http\Response`. It implements `HeaderAwareResponseInterface`, and | |
122 defines the following constructor: | |
123 | |
124 ```php | |
125 namespace Zend\Feed\Reader\Http; | |
126 | |
127 class Response implements HeaderAwareResponseInterface | |
128 { | |
129 /** | |
130 * Constructor | |
131 * | |
132 * @param int $statusCode Response status code | |
133 * @param string $body Response body | |
134 * @param array $headers Response headers, if available | |
135 */ | |
136 public function __construct($statusCode, $body, array $headers = []); | |
137 } | |
138 ``` | |
139 | |
140 ## PSR-7 Response | |
141 | |
142 [PSR-7](http://www.php-fig.org/psr/psr-7/) defines a set of HTTP message | |
143 interfaces, but not a client interface. To facilitate wrapping an HTTP client | |
144 that uses PSR-7 messages, we provide `Zend\Feed\Reader\Psr7ResponseDecorator`: | |
145 | |
146 ```php | |
147 namespace Zend\Feed\Reader\Http; | |
148 | |
149 use Psr\Http\Message\ResponseInterface as PsrResponseInterface; | |
150 | |
151 class Psr7ResponseDecorator implements HeaderAwareResponseInterface | |
152 { | |
153 /** | |
154 * @param PsrResponseInterface $response | |
155 */ | |
156 public function __construct(PsrResponseInterface $response); | |
157 | |
158 /** | |
159 * @return PsrResponseInterface | |
160 */ | |
161 public function getDecoratedResponse(); | |
162 } | |
163 ``` | |
164 | |
165 Clients can then take the PSR-7 response they receive, pass it to the decorator, | |
166 and return the decorator. | |
167 | |
168 To use the PSR-7 response, you will need to add the PSR-7 interfaces to your | |
169 application, if they are not already installed by the client of your choice: | |
170 | |
171 ```bash | |
172 $ composer require psr/http-message | |
173 ``` | |
174 | |
175 ## zend-http | |
176 | |
177 We also provide a zend-http client decorator, | |
178 `Zend\Feed\Reader\Http\ZendHttpClientDecorator`: | |
179 | |
180 ```php | |
181 namespace Zend\Feed\Reader\Http; | |
182 | |
183 use Zend\Http\Client as HttpClient; | |
184 | |
185 class ZendHttpClientDecorator implements HeaderAwareClientInterface | |
186 { | |
187 /** | |
188 * @param HttpClient $client | |
189 */ | |
190 public function __construct(HttpClient $client); | |
191 | |
192 /** | |
193 * @return HttpClient | |
194 */ | |
195 public function getDecoratedClient(); | |
196 } | |
197 ``` | |
198 | |
199 Its `get()` implementation returns a `Response` instance seeded from the | |
200 zend-http response returned, including status, body, and headers. | |
201 | |
202 zend-http is the default implementation assumed by `Zend\Feed\Reader\Reader`, | |
203 but *is not installed by default*. You may install it using composer: | |
204 | |
205 ```bash | |
206 $ composer require zendframework/zend-http | |
207 ``` | |
208 | |
209 ## Providing a client to Reader | |
210 | |
211 By default, `Zend\Feed\Reader\Reader` will lazy load a zend-http client. If you | |
212 have not installed zend-http, however, PHP will raise an error indicating the | |
213 class is not found! | |
214 | |
215 As such, you have two options: | |
216 | |
217 1. Install zend-http: `composer require zendframework/zend-http`. | |
218 2. Inject the `Reader` with your own HTTP client. | |
219 | |
220 To accomplish the second, you will need an implementation of | |
221 `Zend\Feed\Reader\Http\ClientInterface` or `HeaderAwareClientInterface`, and an | |
222 instance of that implementation. Once you do, you can use the static method | |
223 `setHttpClient()` to inject it. | |
224 | |
225 As an example, let's say you've created a PSR-7-based implementation named | |
226 `My\Http\Psr7FeedClient`. You could then do the following: | |
227 | |
228 ```php | |
229 use My\Http\Psr7FeedClient; | |
230 use Zend\Feed\Reader\Reader; | |
231 | |
232 Reader::setHttpClient(new Psr7FeedClient()); | |
233 ``` | |
234 | |
235 Your client will then be used for all `import()` and `findFeedLinks()` | |
236 operations. |