'Continue', 101 => 'Switching Protocols', 102 => 'Processing', // RFC2518 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-Status', // RFC4918 208 => 'Already Reported', // RFC5842 226 => 'IM Used', // RFC3229 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Reserved', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', // RFC7238 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', // RFC2324 422 => 'Unprocessable Entity', // RFC4918 423 => 'Locked', // RFC4918 424 => 'Failed Dependency', // RFC4918 425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817 426 => 'Upgrade Required', // RFC2817 428 => 'Precondition Required', // RFC6585 429 => 'Too Many Requests', // RFC6585 431 => 'Request Header Fields Too Large', // RFC6585 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 506 => 'Variant Also Negotiates (Experimental)', // RFC2295 507 => 'Insufficient Storage', // RFC4918 508 => 'Loop Detected', // RFC5842 510 => 'Not Extended', // RFC2774 511 => 'Network Authentication Required', // RFC6585 ); /** * @var string */ protected $content; /** * @var int */ protected $statusCode; /** * @var string */ protected $statusText; /** * @var array */ public $headers; /** * @var string */ protected $version; /** * Construct the response * * @param mixed $content * @param int $statusCode * @param array $headers */ public function __construct($content = '', $statusCode = 200, $headers = array()) { $this->setContent($content); $this->setStatusCode($statusCode); $this->headers = $headers; $this->version = '1.1'; } /** * Set the content on the response. * * @param mixed $content * @return $this */ public function setContent($content) { if ($content instanceof ArrayObject || is_array($content)) { $this->headers['Content-Type'] = array('application/json'); $content = json_encode($content); } $this->content = $content; } /** * Returns the Response as an HTTP string. * * The string representation of the Response is the same as the * one that will be sent to the client only if the prepare() method * has been called before. * * @return string The Response as an HTTP string * * @see prepare() */ public function __toString() { return sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n". $this->headers."\r\n". $this->getContent(); } /** * Sets the response status code. * * @param int $code HTTP status code * @param mixed $text HTTP status text * * If the status text is null it will be automatically populated for the known * status codes and left empty otherwise. * * @return Response * * @throws \InvalidArgumentException When the HTTP status code is not valid * * @api */ public function setStatusCode($code, $text = null) { $this->statusCode = $code = (int) $code; if ($this->isInvalid()) { throw new InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code)); } if (null === $text) { $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : ''; return $this; } if (false === $text) { $this->statusText = ''; return $this; } $this->statusText = $text; return $this; } // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html /** * Is response invalid? * * @return bool * * @api */ public function isInvalid() { return $this->statusCode < 100 || $this->statusCode >= 600; } /** * Set a header on the Response. * * @param string $key * @param string $value * @param bool $replace * @return $this */ public function header($key, $value, $replace = true) { if (empty($this->headers[$key])) { $this->headers[$key] = array(); } if ($replace) { $this->headers[$key] = array($value); } else { $this->headers[$key][] = $value; } return $this; } /** * Sends HTTP headers and content. * * @return Response * * @api */ public function send() { $this->sendHeaders(); $this->sendContent(); if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } return $this; } /** * Sends content for the current web response. * * @return Response */ public function sendContent() { echo $this->content; return $this; } /** * Sends HTTP headers. * * @return Response */ public function sendHeaders() { // headers have already been sent by the developer if (headers_sent()) { return $this; } // status header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode); // headers foreach ($this->headers as $name => $values) { if (is_array($values)) { foreach ($values as $value) { header($name . ': ' . $value, false, $this->statusCode); } } else { header($name . ': ' . $values, false, $this->statusCode); } } return $this; } }