File indexing completed on 2025-02-16 05:25:42
0001 <?php 0002 0003 /** 0004 * Flooer Framework 0005 * 0006 * LICENSE: BSD License (2 Clause) 0007 * 0008 * @category Flooer 0009 * @package Flooer_Http 0010 * @subpackage Response 0011 * @author Akira Ohgaki <akiraohgaki@gmail.com> 0012 * @copyright Akira Ohgaki 0013 * @license https://opensource.org/licenses/BSD-2-Clause BSD License (2 Clause) 0014 * @link https://github.com/akiraohgaki/flooer 0015 */ 0016 0017 /** 0018 * Usage 0019 * 0020 * $response = new Flooer_Http_Response(); 0021 * $response->setStatus(201); 0022 * $response->setHeader('Content-Type', 'text/html'); 0023 * $response->setBody($data); 0024 * $response->send(); 0025 */ 0026 0027 /** 0028 * HTTP response class 0029 * 0030 * @category Flooer 0031 * @package Flooer_Http 0032 * @subpackage Response 0033 * @author Akira Ohgaki <akiraohgaki@gmail.com> 0034 */ 0035 class Flooer_Http_Response 0036 { 0037 0038 /** 0039 * Configuration options 0040 * 0041 * @var array 0042 */ 0043 protected $_config = array( 0044 'status' => null, 0045 'redirect' => null, 0046 'headers' => array(), 0047 'body' => null, 0048 'replace' => true 0049 ); 0050 0051 /** 0052 * Status codes 0053 * 0054 * @var array 0055 * @link http://www.iana.org/assignments/http-status-codes 0056 */ 0057 protected $_statusCodes = array( 0058 100 => '100 Continue', 0059 101 => '101 Switching Protocols', 0060 102 => '102 Processing', 0061 // 103-199 Unassigned 0062 200 => '200 OK', 0063 201 => '201 Created', 0064 202 => '202 Accepted', 0065 203 => '203 Non-Authoritative Information', 0066 204 => '204 No Content', 0067 205 => '205 Reset Content', 0068 206 => '206 Partial Content', 0069 207 => '207 Multi-Status', 0070 208 => '208 Already Reported', 0071 // 209-225 Unassigned 0072 226 => '226 IM Used', 0073 // 227-299 Unassigned 0074 300 => '300 Multiple Choices', 0075 301 => '301 Moved Permanently', 0076 302 => '302 Found', 0077 303 => '303 See Other', 0078 304 => '304 Not Modified', 0079 305 => '305 Use Proxy', 0080 // 306 Unused 0081 307 => '307 Temporary Redirect', 0082 308 => '308 Permanent Redirect', 0083 // 309-399 Unassigned 0084 400 => '400 Bad Request', 0085 401 => '401 Unauthorized', 0086 402 => '402 Payment Required', 0087 403 => '403 Forbidden', 0088 404 => '404 Not Found', 0089 405 => '405 Method Not Allowed', 0090 406 => '406 Not Acceptable', 0091 407 => '407 Proxy Authentication Required', 0092 408 => '408 Request Timeout', 0093 409 => '409 Conflict', 0094 410 => '410 Gone', 0095 411 => '411 Length Required', 0096 412 => '412 Precondition Failed', 0097 413 => '413 Payload Too Large', 0098 414 => '414 URI Too Long', 0099 415 => '415 Unsupported Media Type', 0100 416 => '416 Range Not Satisfiable', 0101 417 => '417 Expectation Failed', 0102 // 418-420 Unassigned 0103 421 => '421 Misdirected Request', 0104 422 => '422 Unprocessable Entity', 0105 423 => '423 Locked', 0106 424 => '424 Failed Dependency', 0107 // 425 Unassigned 0108 426 => '426 Upgrade Required', 0109 // 427 Unassigned 0110 428 => '428 Precondition Required', 0111 429 => '429 Too Many Requests', 0112 // 430 Unassigned 0113 431 => '431 Request Header Fields Too Large', 0114 // 432-450 Unassigned 0115 451 => '451 Unavailable for Legal Reasons', 0116 // 452-499 Unassigned 0117 500 => '500 Internal Server Error', 0118 501 => '501 Not Implemented', 0119 502 => '502 Bad Gateway', 0120 503 => '503 Service Unavailable', 0121 504 => '504 Gateway Timeout', 0122 505 => '505 HTTP Version Not Supported', 0123 506 => '506 Variant Also Negotiates', 0124 507 => '507 Insufficient Storage', 0125 508 => '508 Loop Detected', 0126 // 509 Unassigned 0127 510 => '510 Not Extended', 0128 511 => '511 Network Authentication Required' 0129 // 512-599 Unassigned 0130 ); 0131 0132 /** 0133 * Content types 0134 * 0135 * @var array 0136 */ 0137 protected $_contentTypes = array( 0138 'xml' => 'application/xml', 0139 'rdf' => 'application/rdf+xml', 0140 'atom' => 'application/atom+xml', 0141 'rss' => 'application/rss+xml', 0142 'xhtml' => 'application/xhtml+xml', 0143 'json' => 'application/json', 0144 'php' => 'text/html', 0145 'phtml' => 'text/html', 0146 'html' => 'text/html', 0147 'txt' => 'text/plain', 0148 'csv' => 'text/csv', 0149 'tsv' => 'text/tab-separated-values', 0150 'vcf' => 'text/x-vcard', 0151 'ics' => 'text/calendar', 0152 'js' => 'text/javascript', 0153 'css' => 'text/css' 0154 ); 0155 0156 /** 0157 * Constructor 0158 * 0159 * @param array $config 0160 * @return void 0161 */ 0162 public function __construct(array $config = null) 0163 { 0164 if ($config) { 0165 $this->_config = $config + $this->_config; 0166 } 0167 } 0168 0169 /** 0170 * Send a response 0171 * 0172 * @return void 0173 */ 0174 public function send() 0175 { 0176 if ($this->_config['status']) { 0177 $this->sendStatus($this->_config['status']); 0178 } 0179 if ($this->_config['redirect']) { 0180 $this->redirect($this->_config['redirect']); 0181 } 0182 if ($this->_config['headers']) { 0183 foreach ($this->_config['headers'] as $name => $value) { 0184 $this->sendHeader($name, $value); 0185 } 0186 } 0187 if ($this->_config['body']) { 0188 echo $this->_config['body']; 0189 } 0190 } 0191 0192 /** 0193 * Send a status code 0194 * 0195 * @param int $code 0196 * @return void 0197 */ 0198 public function sendStatus($code) 0199 { 0200 if (isset($this->_statusCodes[$code])) { 0201 header( 0202 $_SERVER['SERVER_PROTOCOL'] . ' ' . $this->_statusCodes[$code], 0203 $this->_config['replace'] 0204 ); 0205 header( 0206 'Status: ' . $this->_statusCodes[$code], 0207 $this->_config['replace'], 0208 $code 0209 ); 0210 } 0211 } 0212 0213 /** 0214 * Redirection 0215 * 0216 * @param string $location 0217 * @return void 0218 */ 0219 public function redirect($location) 0220 { 0221 header('Location: ' . $location, true); 0222 exit; 0223 } 0224 0225 /** 0226 * Send a response header 0227 * 0228 * @param string $name 0229 * @param string $value 0230 * @return void 0231 */ 0232 public function sendHeader($name, $value) 0233 { 0234 header($name . ': ' . $value, $this->_config['replace']); 0235 } 0236 0237 /** 0238 * Detect a content type 0239 * 0240 * @param string $filename 0241 * @return string|null 0242 */ 0243 public function detectContentType($filename) 0244 { 0245 $type = null; 0246 if (preg_match("/.+\.([^\.]+)$/", strtolower($filename), $matches) 0247 && isset($this->_contentTypes[$matches[1]]) 0248 ) { 0249 $type = $this->_contentTypes[$matches[1]]; 0250 if (extension_loaded('mbstring') && mb_http_output() != 'pass') { 0251 $type .= '; charset=' . mb_http_output(); 0252 } 0253 } 0254 return $type; 0255 } 0256 0257 /** 0258 * Set a status code 0259 * 0260 * @param int $code 0261 * @return void 0262 */ 0263 public function setStatus($code) 0264 { 0265 $this->_config['status'] = $code; 0266 } 0267 0268 /** 0269 * Get a status code 0270 * 0271 * @return int 0272 */ 0273 public function getStatus() 0274 { 0275 return $this->_config['status']; 0276 } 0277 0278 /** 0279 * Set a redirect location 0280 * 0281 * @param string $location 0282 * @return void 0283 */ 0284 public function setRedirect($location) 0285 { 0286 $this->_config['redirect'] = $location; 0287 } 0288 0289 /** 0290 * Get a redirect location 0291 * 0292 * @return string 0293 */ 0294 public function getRedirect() 0295 { 0296 return $this->_config['redirect']; 0297 } 0298 0299 /** 0300 * Set a response headers 0301 * 0302 * @param array $headers 0303 * @return void 0304 */ 0305 public function setHeaders(array $headers) 0306 { 0307 $this->_config['headers'] = $headers; 0308 } 0309 0310 /** 0311 * Get a response headers 0312 * 0313 * @return array 0314 */ 0315 public function getHeaders() 0316 { 0317 return $this->_config['headers']; 0318 } 0319 0320 /** 0321 * Set a response header 0322 * 0323 * @param string $name 0324 * @param string $value 0325 * @return void 0326 */ 0327 public function setHeader($name, $value) 0328 { 0329 $this->_config['headers'][$name] = $value; 0330 } 0331 0332 /** 0333 * Get a response header 0334 * 0335 * @param string $name 0336 * @return string|null 0337 */ 0338 public function getHeader($name) 0339 { 0340 if (isset($this->_config['headers'][$name])) { 0341 return $this->_config['headers'][$name]; 0342 } 0343 return null; 0344 } 0345 0346 /** 0347 * Set a response body data 0348 * 0349 * @param mixed $data 0350 * @return void 0351 */ 0352 public function setBody($data) 0353 { 0354 $this->_config['body'] = $data; 0355 } 0356 0357 /** 0358 * Get a response body data 0359 * 0360 * @return mixed 0361 */ 0362 public function getBody() 0363 { 0364 return $this->_config['body']; 0365 } 0366 0367 /** 0368 * Set a header replace option 0369 * 0370 * @param bool $replace 0371 * @return void 0372 */ 0373 public function setReplace($replace) 0374 { 0375 $this->_config['replace'] = $replace; 0376 } 0377 0378 /** 0379 * Get a header replace option 0380 * 0381 * @return bool 0382 */ 0383 public function getReplace() 0384 { 0385 return $this->_config['replace']; 0386 } 0387 0388 }