3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
12 use Zend\Stdlib\Parameters
;
13 use Zend\Stdlib\ParametersInterface
;
14 use Zend\Stdlib\RequestInterface
;
15 use Zend\Uri\Exception
as UriException
;
16 use Zend\Uri\Http
as HttpUri
;
21 * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5
23 class Request
extends AbstractMessage
implements RequestInterface
26 * @const string METHOD constant names
28 const METHOD_OPTIONS
= 'OPTIONS';
29 const METHOD_GET
= 'GET';
30 const METHOD_HEAD
= 'HEAD';
31 const METHOD_POST
= 'POST';
32 const METHOD_PUT
= 'PUT';
33 const METHOD_DELETE
= 'DELETE';
34 const METHOD_TRACE
= 'TRACE';
35 const METHOD_CONNECT
= 'CONNECT';
36 const METHOD_PATCH
= 'PATCH';
37 const METHOD_PROPFIND
= 'PROPFIND';
43 protected $method = self
::METHOD_GET
;
48 protected $uri = null;
51 * @var ParametersInterface
53 protected $queryParams = null;
56 * @var ParametersInterface
58 protected $postParams = null;
61 * @var ParametersInterface
63 protected $fileParams = null;
66 * A factory that produces a Request object from a well-formed Http Request string
68 * @param string $string
70 * @throws Exception\InvalidArgumentException
72 public static function fromString($string)
74 $request = new static();
76 $lines = explode("\r\n", $string);
78 // first line must be Method/Uri/Version string
80 $methods = implode('|', array(
81 self
::METHOD_OPTIONS
, self
::METHOD_GET
, self
::METHOD_HEAD
, self
::METHOD_POST
,
82 self
::METHOD_PUT
, self
::METHOD_DELETE
, self
::METHOD_TRACE
, self
::METHOD_CONNECT
,
85 $regex = '#^(?P<method>' . $methods . ')\s(?P<uri>[^ ]*)(?:\sHTTP\/(?P<version>\d+\.\d+)){0,1}#';
86 $firstLine = array_shift($lines);
87 if (!preg_match($regex, $firstLine, $matches)) {
88 throw new Exception\
InvalidArgumentException(
89 'A valid request line was not found in the provided string'
93 $request->setMethod($matches['method']);
94 $request->setUri($matches['uri']);
96 if (isset($matches['version'])) {
97 $request->setVersion($matches['version']);
100 if (count($lines) == 0) {
105 $headers = $rawBody = array();
107 $nextLine = array_shift($lines);
108 if ($nextLine == '') {
113 $headers[] = $nextLine;
115 $rawBody[] = $nextLine;
120 $request->headers
= implode("\r\n", $headers);
124 $request->setContent(implode("\r\n", $rawBody));
131 * Set the method for this request
133 * @param string $method
135 * @throws Exception\InvalidArgumentException
137 public function setMethod($method)
139 $method = strtoupper($method);
140 if (!defined('static::METHOD_' . $method)) {
141 throw new Exception\
InvalidArgumentException('Invalid HTTP method passed');
143 $this->method
= $method;
148 * Return the method for this request
152 public function getMethod()
154 return $this->method
;
158 * Set the URI/URL for this request, this can be a string or an instance of Zend\Uri\Http
160 * @throws Exception\InvalidArgumentException
161 * @param string|HttpUri $uri
164 public function setUri($uri)
166 if (is_string($uri)) {
168 $uri = new HttpUri($uri);
169 } catch (UriException\InvalidUriPartException
$e) {
170 throw new Exception\
InvalidArgumentException(
171 sprintf('Invalid URI passed as string (%s)', (string) $uri),
176 } elseif (!($uri instanceof HttpUri
)) {
177 throw new Exception\
InvalidArgumentException(
178 'URI must be an instance of Zend\Uri\Http or a string'
187 * Return the URI for this request object
191 public function getUri()
193 if ($this->uri
=== null ||
is_string($this->uri
)) {
194 $this->uri
= new HttpUri($this->uri
);
200 * Return the URI for this request object as a string
204 public function getUriString()
206 if ($this->uri
instanceof HttpUri
) {
207 return $this->uri
->toString();
213 * Provide an alternate Parameter Container implementation for query parameters in this object,
214 * (this is NOT the primary API for value setting, for that see getQuery())
216 * @param \Zend\Stdlib\ParametersInterface $query
219 public function setQuery(ParametersInterface
$query)
221 $this->queryParams
= $query;
226 * Return the parameter container responsible for query parameters or a single query parameter
228 * @param string|null $name Parameter name to retrieve, or null to get the whole container.
229 * @param mixed|null $default Default value to use when the parameter is missing.
230 * @return \Zend\Stdlib\ParametersInterface|mixed
232 public function getQuery($name = null, $default = null)
234 if ($this->queryParams
=== null) {
235 $this->queryParams
= new Parameters();
238 if ($name === null) {
239 return $this->queryParams
;
242 return $this->queryParams
->get($name, $default);
246 * Provide an alternate Parameter Container implementation for post parameters in this object,
247 * (this is NOT the primary API for value setting, for that see getPost())
249 * @param \Zend\Stdlib\ParametersInterface $post
252 public function setPost(ParametersInterface
$post)
254 $this->postParams
= $post;
259 * Return the parameter container responsible for post parameters or a single post parameter.
261 * @param string|null $name Parameter name to retrieve, or null to get the whole container.
262 * @param mixed|null $default Default value to use when the parameter is missing.
263 * @return \Zend\Stdlib\ParametersInterface|mixed
265 public function getPost($name = null, $default = null)
267 if ($this->postParams
=== null) {
268 $this->postParams
= new Parameters();
271 if ($name === null) {
272 return $this->postParams
;
275 return $this->postParams
->get($name, $default);
279 * Return the Cookie header, this is the same as calling $request->getHeaders()->get('Cookie');
281 * @convenience $request->getHeaders()->get('Cookie');
282 * @return Header\Cookie
284 public function getCookie()
286 return $this->getHeaders()->get('Cookie');
290 * Provide an alternate Parameter Container implementation for file parameters in this object,
291 * (this is NOT the primary API for value setting, for that see getFiles())
293 * @param ParametersInterface $files
296 public function setFiles(ParametersInterface
$files)
298 $this->fileParams
= $files;
303 * Return the parameter container responsible for file parameters or a single file.
305 * @param string|null $name Parameter name to retrieve, or null to get the whole container.
306 * @param mixed|null $default Default value to use when the parameter is missing.
307 * @return ParametersInterface|mixed
309 public function getFiles($name = null, $default = null)
311 if ($this->fileParams
=== null) {
312 $this->fileParams
= new Parameters();
315 if ($name === null) {
316 return $this->fileParams
;
319 return $this->fileParams
->get($name, $default);
323 * Return the header container responsible for headers or all headers of a certain name/type
325 * @see \Zend\Http\Headers::get()
326 * @param string|null $name Header name to retrieve, or null to get the whole container.
327 * @param mixed|null $default Default value to use when the requested header is missing.
328 * @return \Zend\Http\Headers|bool|\Zend\Http\Header\HeaderInterface|\ArrayIterator
330 public function getHeaders($name = null, $default = false)
332 if ($this->headers
=== null ||
is_string($this->headers
)) {
333 // this is only here for fromString lazy loading
334 $this->headers
= (is_string($this->headers
)) ? Headers
::fromString($this->headers
) : new Headers();
337 if ($name === null) {
338 return $this->headers
;
341 if ($this->headers
->has($name)) {
342 return $this->headers
->get($name);
349 * Get all headers of a certain name/type.
351 * @see Request::getHeaders()
352 * @param string|null $name Header name to retrieve, or null to get the whole container.
353 * @param mixed|null $default Default value to use when the requested header is missing.
354 * @return \Zend\Http\Headers|bool|\Zend\Http\Header\HeaderInterface|\ArrayIterator
356 public function getHeader($name, $default = false)
358 return $this->getHeaders($name, $default);
362 * Is this an OPTIONS method request?
366 public function isOptions()
368 return ($this->method
=== self
::METHOD_OPTIONS
);
372 * Is this a PROPFIND method request?
376 public function isPropFind()
378 return ($this->method
=== self
::METHOD_PROPFIND
);
382 * Is this a GET method request?
386 public function isGet()
388 return ($this->method
=== self
::METHOD_GET
);
392 * Is this a HEAD method request?
396 public function isHead()
398 return ($this->method
=== self
::METHOD_HEAD
);
402 * Is this a POST method request?
406 public function isPost()
408 return ($this->method
=== self
::METHOD_POST
);
412 * Is this a PUT method request?
416 public function isPut()
418 return ($this->method
=== self
::METHOD_PUT
);
422 * Is this a DELETE method request?
426 public function isDelete()
428 return ($this->method
=== self
::METHOD_DELETE
);
432 * Is this a TRACE method request?
436 public function isTrace()
438 return ($this->method
=== self
::METHOD_TRACE
);
442 * Is this a CONNECT method request?
446 public function isConnect()
448 return ($this->method
=== self
::METHOD_CONNECT
);
452 * Is this a PATCH method request?
456 public function isPatch()
458 return ($this->method
=== self
::METHOD_PATCH
);
462 * Is the request a Javascript XMLHttpRequest?
464 * Should work with Prototype/Script.aculo.us, possibly others.
468 public function isXmlHttpRequest()
470 $header = $this->getHeaders()->get('X_REQUESTED_WITH');
471 return false !== $header && $header->getFieldValue() == 'XMLHttpRequest';
475 * Is this a Flash request?
479 public function isFlashRequest()
481 $header = $this->getHeaders()->get('USER_AGENT');
482 return false !== $header && stristr($header->getFieldValue(), ' flash');
486 * Return the formatted request line (first line) for this http request
490 public function renderRequestLine()
492 return $this->method
. ' ' . (string) $this->uri
. ' HTTP/' . $this->version
;
498 public function toString()
500 $str = $this->renderRequestLine() . "\r\n";
501 $str .= $this->getHeaders()->toString();
503 $str .= $this->getContent();