These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Kotori.php |
||
4 | * |
||
5 | * A Tiny Model-View-Controller PHP Framework |
||
6 | * |
||
7 | * This content is released under the Apache 2 License |
||
8 | * |
||
9 | * Copyright (c) 2015-2017 Kotori Technology. All rights reserved. |
||
10 | * |
||
11 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
12 | * you may not use this file except in compliance with the License. |
||
13 | * You may obtain a copy of the License at |
||
14 | * |
||
15 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
16 | * |
||
17 | * Unless required by applicable law or agreed to in writing, software |
||
18 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
19 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
20 | * See the License for the specific language governing permissions and |
||
21 | * limitations under the License. |
||
22 | */ |
||
23 | |||
24 | /** |
||
25 | * Response Class |
||
26 | * |
||
27 | * @package Kotori |
||
28 | * @subpackage Http |
||
29 | * @author Kokororin |
||
30 | * @link https://kotori.love |
||
31 | */ |
||
32 | namespace Kotori\Http; |
||
33 | |||
34 | use Kotori\Debug\Hook; |
||
35 | use Kotori\Exception\ResponseException; |
||
36 | |||
37 | class Response |
||
38 | { |
||
39 | /** |
||
40 | * Status array |
||
41 | * |
||
42 | * @var array |
||
43 | */ |
||
44 | protected $httpCode = [ |
||
45 | 100 => 'Continue', |
||
46 | 101 => 'Switching Protocols', |
||
47 | 200 => 'OK', |
||
48 | 201 => 'Created', |
||
49 | 202 => 'Accepted', |
||
50 | 203 => 'Non-Authoritative Information', |
||
51 | 204 => 'No Content', |
||
52 | 205 => 'Reset Content', |
||
53 | 206 => 'Partial Content', |
||
54 | 300 => 'Multiple Choices', |
||
55 | 301 => 'Moved Permanently', |
||
56 | 302 => 'Found', |
||
57 | 303 => 'See Other', |
||
58 | 304 => 'Not Modified', |
||
59 | 305 => 'Use Proxy', |
||
60 | 307 => 'Temporary Redirect', |
||
61 | 400 => 'Bad Request', |
||
62 | 401 => 'Unauthorized', |
||
63 | 403 => 'Forbidden', |
||
64 | 404 => 'Not Found', |
||
65 | 405 => 'Method Not Allowed', |
||
66 | 406 => 'Not Acceptable', |
||
67 | 407 => 'Proxy Authentication Required', |
||
68 | 408 => 'Request Timeout', |
||
69 | 409 => 'Conflict', |
||
70 | 410 => 'Gone', |
||
71 | 411 => 'Length Required', |
||
72 | 412 => 'Precondition Failed', |
||
73 | 413 => 'Request Entity Too Large', |
||
74 | 414 => 'Request-URI Too Long', |
||
75 | 415 => 'Unsupported Media Type', |
||
76 | 416 => 'Requested Range Not Satisfiable', |
||
77 | 417 => 'Expectation Failed', |
||
78 | 422 => 'Unprocessable Entity', |
||
79 | 500 => 'Internal Server Error', |
||
80 | 501 => 'Not Implemented', |
||
81 | 502 => 'Bad Gateway', |
||
82 | 503 => 'Service Unavailable', |
||
83 | 504 => 'Gateway Timeout', |
||
84 | 505 => 'HTTP Version Not Supported', |
||
85 | ]; |
||
86 | |||
87 | /** |
||
88 | * Default Charset |
||
89 | * |
||
90 | * @var string |
||
91 | */ |
||
92 | protected $charset = null; |
||
93 | |||
94 | /** |
||
95 | * Class constructor |
||
96 | * |
||
97 | * Initialize Response. |
||
98 | * |
||
99 | * @return void |
||
100 | */ |
||
101 | public function __construct() |
||
102 | { |
||
103 | Hook::listen(__CLASS__); |
||
104 | $this->setCharset('UTF-8'); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Get current charset |
||
109 | * |
||
110 | * @return string |
||
111 | */ |
||
112 | public function getCharset() |
||
113 | { |
||
114 | return $this->charset; |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * Set current charset |
||
119 | * |
||
120 | * @return void |
||
121 | */ |
||
122 | public function setCharset($charset = null) |
||
123 | { |
||
124 | $this->charset = empty($charset) ? 'UTF-8' : $charset; |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * Set HTTP Status Header |
||
129 | * |
||
130 | * @param int $code |
||
131 | * @param string $text |
||
132 | * @return void |
||
133 | * |
||
134 | * @throws \Kotori\Exception\ResponseException |
||
135 | */ |
||
136 | public function setStatus($code = 200, $text = '') |
||
137 | { |
||
138 | if (empty($code) or !is_numeric($code)) { |
||
139 | throw new ResponseException('Status codes must be numeric.'); |
||
140 | } |
||
141 | |||
142 | if (empty($text)) { |
||
143 | if (!is_int($code)) { |
||
144 | $code = (int) $code; |
||
145 | } |
||
146 | |||
147 | if (isset($this->httpCode[$code])) { |
||
148 | $text = $this->httpCode[$code]; |
||
149 | } else { |
||
150 | throw new ResponseException('No status text available. Please check your status code number or supply your own message text.'); |
||
151 | } |
||
152 | } |
||
153 | |||
154 | if (strpos(PHP_SAPI, 'cgi') === 0) { |
||
155 | header('Status: ' . $code . ' ' . $text, true); |
||
156 | } else { |
||
157 | $server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; |
||
158 | header($server_protocol . ' ' . $code . ' ' . $text, true, $code); |
||
159 | } |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * Set Header |
||
164 | * |
||
165 | * Lets you set a server header which will be sent with the final output. |
||
166 | * |
||
167 | * @param string $name |
||
168 | * @param string $value |
||
169 | * @return void |
||
170 | */ |
||
171 | public function setHeader($name, $value) |
||
172 | { |
||
173 | header($name . ': ' . $value, true); |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * Set Content-Type |
||
178 | * |
||
179 | * Let you set a Content-Type header |
||
180 | * |
||
181 | * @param string $contentType |
||
182 | * @return void |
||
183 | */ |
||
184 | public function setContentType($contentType = 'text/html') |
||
185 | { |
||
186 | header('Content-Type: ' . $contentType . '; charset=' . $this->getCharset(), true); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Thown JSON to output |
||
191 | * |
||
192 | * @param mixed $data |
||
193 | * @return void |
||
194 | */ |
||
195 | public function throwJSON($data) |
||
196 | { |
||
197 | $this->setContentType('application/json'); |
||
198 | exit(json_encode($data)); |
||
0 ignored issues
–
show
|
|||
199 | } |
||
200 | |||
201 | /** |
||
202 | * Header Redirect |
||
203 | * |
||
204 | * @param string $location |
||
205 | * @param boolean $isPermanently |
||
206 | * @return void |
||
207 | */ |
||
208 | public function redirect($location, $isPermanently = false) |
||
209 | { |
||
210 | if ($isPermanently) { |
||
211 | header('Location: ' . $location, false, 301); |
||
212 | exit; |
||
0 ignored issues
–
show
The method
redirect() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
213 | } else { |
||
214 | header('Location: ' . $location, false, 302); |
||
215 | exit; |
||
0 ignored issues
–
show
The method
redirect() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
216 | } |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Output static file with 304 header |
||
221 | * |
||
222 | * @return void |
||
223 | */ |
||
224 | public function setCacheHeader() |
||
225 | { |
||
226 | if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { |
||
227 | $this->setStatus(304); |
||
228 | exit; |
||
0 ignored issues
–
show
The method
setCacheHeader() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
|||
229 | } |
||
230 | |||
231 | $this->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 365 * 24 * 60 * 60) . ' GMT'); |
||
232 | $this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT'); |
||
233 | $this->setHeader('Cache-Control', 'immutable'); |
||
234 | } |
||
235 | |||
236 | } |
||
237 |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.