comparison vendor/guzzlehttp/psr7/src/ServerRequest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 129ea1e6d783
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 namespace GuzzleHttp\Psr7;
4
5 use InvalidArgumentException;
6 use Psr\Http\Message\ServerRequestInterface;
7 use Psr\Http\Message\UriInterface;
8 use Psr\Http\Message\StreamInterface;
9 use Psr\Http\Message\UploadedFileInterface;
10
11 /**
12 * Server-side HTTP request
13 *
14 * Extends the Request definition to add methods for accessing incoming data,
15 * specifically server parameters, cookies, matched path parameters, query
16 * string arguments, body parameters, and upload file information.
17 *
18 * "Attributes" are discovered via decomposing the request (and usually
19 * specifically the URI path), and typically will be injected by the application.
20 *
21 * Requests are considered immutable; all methods that might change state are
22 * implemented such that they retain the internal state of the current
23 * message and return a new instance that contains the changed state.
24 */
25 class ServerRequest extends Request implements ServerRequestInterface
26 {
27 /**
28 * @var array
29 */
30 private $attributes = [];
31
32 /**
33 * @var array
34 */
35 private $cookieParams = [];
36
37 /**
38 * @var null|array|object
39 */
40 private $parsedBody;
41
42 /**
43 * @var array
44 */
45 private $queryParams = [];
46
47 /**
48 * @var array
49 */
50 private $serverParams;
51
52 /**
53 * @var array
54 */
55 private $uploadedFiles = [];
56
57 /**
58 * @param string $method HTTP method
59 * @param string|UriInterface $uri URI
60 * @param array $headers Request headers
61 * @param string|null|resource|StreamInterface $body Request body
62 * @param string $version Protocol version
63 * @param array $serverParams Typically the $_SERVER superglobal
64 */
65 public function __construct(
66 $method,
67 $uri,
68 array $headers = [],
69 $body = null,
70 $version = '1.1',
71 array $serverParams = []
72 ) {
73 $this->serverParams = $serverParams;
74
75 parent::__construct($method, $uri, $headers, $body, $version);
76 }
77
78 /**
79 * Return an UploadedFile instance array.
80 *
81 * @param array $files A array which respect $_FILES structure
82 * @throws InvalidArgumentException for unrecognized values
83 * @return array
84 */
85 public static function normalizeFiles(array $files)
86 {
87 $normalized = [];
88
89 foreach ($files as $key => $value) {
90 if ($value instanceof UploadedFileInterface) {
91 $normalized[$key] = $value;
92 } elseif (is_array($value) && isset($value['tmp_name'])) {
93 $normalized[$key] = self::createUploadedFileFromSpec($value);
94 } elseif (is_array($value)) {
95 $normalized[$key] = self::normalizeFiles($value);
96 continue;
97 } else {
98 throw new InvalidArgumentException('Invalid value in files specification');
99 }
100 }
101
102 return $normalized;
103 }
104
105 /**
106 * Create and return an UploadedFile instance from a $_FILES specification.
107 *
108 * If the specification represents an array of values, this method will
109 * delegate to normalizeNestedFileSpec() and return that return value.
110 *
111 * @param array $value $_FILES struct
112 * @return array|UploadedFileInterface
113 */
114 private static function createUploadedFileFromSpec(array $value)
115 {
116 if (is_array($value['tmp_name'])) {
117 return self::normalizeNestedFileSpec($value);
118 }
119
120 return new UploadedFile(
121 $value['tmp_name'],
122 (int) $value['size'],
123 (int) $value['error'],
124 $value['name'],
125 $value['type']
126 );
127 }
128
129 /**
130 * Normalize an array of file specifications.
131 *
132 * Loops through all nested files and returns a normalized array of
133 * UploadedFileInterface instances.
134 *
135 * @param array $files
136 * @return UploadedFileInterface[]
137 */
138 private static function normalizeNestedFileSpec(array $files = [])
139 {
140 $normalizedFiles = [];
141
142 foreach (array_keys($files['tmp_name']) as $key) {
143 $spec = [
144 'tmp_name' => $files['tmp_name'][$key],
145 'size' => $files['size'][$key],
146 'error' => $files['error'][$key],
147 'name' => $files['name'][$key],
148 'type' => $files['type'][$key],
149 ];
150 $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec);
151 }
152
153 return $normalizedFiles;
154 }
155
156 /**
157 * Return a ServerRequest populated with superglobals:
158 * $_GET
159 * $_POST
160 * $_COOKIE
161 * $_FILES
162 * $_SERVER
163 *
164 * @return ServerRequestInterface
165 */
166 public static function fromGlobals()
167 {
168 $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
169 $headers = function_exists('getallheaders') ? getallheaders() : [];
170 $uri = self::getUriFromGlobals();
171 $body = new LazyOpenStream('php://input', 'r+');
172 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1';
173
174 $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER);
175
176 return $serverRequest
177 ->withCookieParams($_COOKIE)
178 ->withQueryParams($_GET)
179 ->withParsedBody($_POST)
180 ->withUploadedFiles(self::normalizeFiles($_FILES));
181 }
182
183 /**
184 * Get a Uri populated with values from $_SERVER.
185 *
186 * @return UriInterface
187 */
188 public static function getUriFromGlobals() {
189 $uri = new Uri('');
190
191 $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
192
193 $hasPort = false;
194 if (isset($_SERVER['HTTP_HOST'])) {
195 $hostHeaderParts = explode(':', $_SERVER['HTTP_HOST']);
196 $uri = $uri->withHost($hostHeaderParts[0]);
197 if (isset($hostHeaderParts[1])) {
198 $hasPort = true;
199 $uri = $uri->withPort($hostHeaderParts[1]);
200 }
201 } elseif (isset($_SERVER['SERVER_NAME'])) {
202 $uri = $uri->withHost($_SERVER['SERVER_NAME']);
203 } elseif (isset($_SERVER['SERVER_ADDR'])) {
204 $uri = $uri->withHost($_SERVER['SERVER_ADDR']);
205 }
206
207 if (!$hasPort && isset($_SERVER['SERVER_PORT'])) {
208 $uri = $uri->withPort($_SERVER['SERVER_PORT']);
209 }
210
211 $hasQuery = false;
212 if (isset($_SERVER['REQUEST_URI'])) {
213 $requestUriParts = explode('?', $_SERVER['REQUEST_URI']);
214 $uri = $uri->withPath($requestUriParts[0]);
215 if (isset($requestUriParts[1])) {
216 $hasQuery = true;
217 $uri = $uri->withQuery($requestUriParts[1]);
218 }
219 }
220
221 if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) {
222 $uri = $uri->withQuery($_SERVER['QUERY_STRING']);
223 }
224
225 return $uri;
226 }
227
228
229 /**
230 * {@inheritdoc}
231 */
232 public function getServerParams()
233 {
234 return $this->serverParams;
235 }
236
237 /**
238 * {@inheritdoc}
239 */
240 public function getUploadedFiles()
241 {
242 return $this->uploadedFiles;
243 }
244
245 /**
246 * {@inheritdoc}
247 */
248 public function withUploadedFiles(array $uploadedFiles)
249 {
250 $new = clone $this;
251 $new->uploadedFiles = $uploadedFiles;
252
253 return $new;
254 }
255
256 /**
257 * {@inheritdoc}
258 */
259 public function getCookieParams()
260 {
261 return $this->cookieParams;
262 }
263
264 /**
265 * {@inheritdoc}
266 */
267 public function withCookieParams(array $cookies)
268 {
269 $new = clone $this;
270 $new->cookieParams = $cookies;
271
272 return $new;
273 }
274
275 /**
276 * {@inheritdoc}
277 */
278 public function getQueryParams()
279 {
280 return $this->queryParams;
281 }
282
283 /**
284 * {@inheritdoc}
285 */
286 public function withQueryParams(array $query)
287 {
288 $new = clone $this;
289 $new->queryParams = $query;
290
291 return $new;
292 }
293
294 /**
295 * {@inheritdoc}
296 */
297 public function getParsedBody()
298 {
299 return $this->parsedBody;
300 }
301
302 /**
303 * {@inheritdoc}
304 */
305 public function withParsedBody($data)
306 {
307 $new = clone $this;
308 $new->parsedBody = $data;
309
310 return $new;
311 }
312
313 /**
314 * {@inheritdoc}
315 */
316 public function getAttributes()
317 {
318 return $this->attributes;
319 }
320
321 /**
322 * {@inheritdoc}
323 */
324 public function getAttribute($attribute, $default = null)
325 {
326 if (false === array_key_exists($attribute, $this->attributes)) {
327 return $default;
328 }
329
330 return $this->attributes[$attribute];
331 }
332
333 /**
334 * {@inheritdoc}
335 */
336 public function withAttribute($attribute, $value)
337 {
338 $new = clone $this;
339 $new->attributes[$attribute] = $value;
340
341 return $new;
342 }
343
344 /**
345 * {@inheritdoc}
346 */
347 public function withoutAttribute($attribute)
348 {
349 if (false === array_key_exists($attribute, $this->attributes)) {
350 return $this;
351 }
352
353 $new = clone $this;
354 unset($new->attributes[$attribute]);
355
356 return $new;
357 }
358 }