|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Koch Framework |
|
5
|
|
|
* Jens-André Koch © 2005 - onwards. |
|
6
|
|
|
* |
|
7
|
|
|
* This file is part of "Koch Framework". |
|
8
|
|
|
* |
|
9
|
|
|
* License: GNU/GPL v2 or any later version, see LICENSE file. |
|
10
|
|
|
* |
|
11
|
|
|
* This program is free software; you can redistribute it and/or modify |
|
12
|
|
|
* it under the terms of the GNU General Public License as published by |
|
13
|
|
|
* the Free Software Foundation; either version 2 of the License, or |
|
14
|
|
|
* (at your option) any later version. |
|
15
|
|
|
* |
|
16
|
|
|
* This program is distributed in the hope that it will be useful, |
|
17
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
18
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
19
|
|
|
* GNU General Public License for more details. |
|
20
|
|
|
* |
|
21
|
|
|
* You should have received a copy of the GNU General Public License |
|
22
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
23
|
|
|
*/ |
|
24
|
|
|
|
|
25
|
|
|
namespace Koch\Http; |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* Koch Framework - Class for Response Handling. |
|
29
|
|
|
* |
|
30
|
|
|
* This class represents the web response object on a request processed by Koch Framework. |
|
31
|
|
|
*/ |
|
32
|
|
|
class HttpResponse implements HttpResponseInterface |
|
|
|
|
|
|
33
|
|
|
{ |
|
34
|
|
|
/** |
|
35
|
|
|
* Status of the response as integer value. |
|
36
|
|
|
* $statusCode = '200' => 'OK'. |
|
37
|
|
|
* |
|
38
|
|
|
* @var int |
|
39
|
|
|
*/ |
|
40
|
|
|
private static $statusCode = '200'; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* @var array Array holding the response headers. |
|
44
|
|
|
*/ |
|
45
|
|
|
private static $headers = []; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* @var string String holding the response content (body). |
|
49
|
|
|
*/ |
|
50
|
|
|
private static $content = null; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* @var string String holding the content type. |
|
54
|
|
|
*/ |
|
55
|
|
|
private static $content_type = 'text/html'; |
|
|
|
|
|
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* Sets the HTTP Status Code for this response. |
|
59
|
|
|
* This method is also used to set the return status code when there |
|
60
|
|
|
* is no error (for example for the status codes 200 (OK) or 301 (Moved permanently) ). |
|
61
|
|
|
* |
|
62
|
|
|
* @param int $statusCode The status code to set |
|
63
|
|
|
*/ |
|
64
|
|
|
public static function setStatusCode($statusCode) |
|
65
|
|
|
{ |
|
66
|
|
|
self::$statusCode = (string) $statusCode; |
|
|
|
|
|
|
67
|
|
|
} |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* Returns the HTTP Status Code. |
|
71
|
|
|
* |
|
72
|
|
|
* @return int HTTP Status Code. |
|
73
|
|
|
*/ |
|
74
|
|
|
public static function getStatusCode() |
|
75
|
|
|
{ |
|
76
|
|
|
return self::$statusCode; |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
|
|
/** |
|
80
|
|
|
* Returns the HTTP 1.1 status code description for a given status code. |
|
81
|
|
|
* |
|
82
|
|
|
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html |
|
83
|
|
|
*/ |
|
84
|
|
|
public static function getStatusCodeDescription($statusCode) |
|
|
|
|
|
|
85
|
|
|
{ |
|
86
|
|
|
/** |
|
87
|
|
|
* Array holding some often occuring status descriptions. |
|
88
|
|
|
* |
|
89
|
|
|
* @var array |
|
90
|
|
|
*/ |
|
91
|
|
|
static $statusCodes = [ |
|
92
|
|
|
// Successful |
|
93
|
|
|
'200' => 'OK', |
|
94
|
|
|
'201' => 'Created', |
|
95
|
|
|
'202' => 'Accepted', |
|
96
|
|
|
// Redirection |
|
97
|
|
|
'301' => 'Moved Permanently', |
|
98
|
|
|
'302' => 'Found', |
|
99
|
|
|
'303' => 'See Other', |
|
100
|
|
|
'304' => 'Not Modified', |
|
101
|
|
|
'307' => 'Temporary Redirect', |
|
102
|
|
|
// Client Error |
|
103
|
|
|
'400' => 'Bad Request', |
|
104
|
|
|
'401' => 'Unauthorized', |
|
105
|
|
|
'403' => 'Forbidden', |
|
106
|
|
|
'404' => 'Not Found', |
|
107
|
|
|
// Server Error |
|
108
|
|
|
'500' => 'Internal Server Error', |
|
109
|
|
|
'502' => 'Bad Gateway', |
|
110
|
|
|
'503' => 'Service Temporarily Unavailable', |
|
111
|
|
|
]; |
|
112
|
|
|
|
|
113
|
|
|
return $statusCodes[$statusCode]; |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
/** |
|
117
|
|
|
* Adds a header to the response array, which is send to the browser. |
|
118
|
|
|
* |
|
119
|
|
|
* @param string $name the name of the header |
|
120
|
|
|
* @param string $value the value of the header |
|
121
|
|
|
*/ |
|
122
|
|
|
public static function addHeader($name, $value) |
|
123
|
|
|
{ |
|
124
|
|
|
self::$headers[$name] = $value; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* setContent appends or replaces the content of the http response buffer. |
|
129
|
|
|
* |
|
130
|
|
|
* appends content to the response body. |
|
131
|
|
|
* when $replace is true, the bodycontent is replaced. |
|
132
|
|
|
* |
|
133
|
|
|
* @param string $content Content to store in the buffer |
|
134
|
|
|
* @param bool $replace Toggle between append or replace. |
|
135
|
|
|
*/ |
|
136
|
|
|
public static function setContent($content, $replace = false) |
|
137
|
|
|
{ |
|
138
|
|
|
// check, if the content should be replaced |
|
139
|
|
|
if ($replace === false) { |
|
140
|
|
|
// no, just append the content |
|
141
|
|
|
self::$content .= $content; |
|
142
|
|
|
} else { |
|
143
|
|
|
// replace the body with the content |
|
144
|
|
|
self::$content = $content; |
|
145
|
|
|
} |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
/** |
|
149
|
|
|
* get content retunrs the response body. |
|
150
|
|
|
*/ |
|
151
|
|
|
public static function getContent() |
|
152
|
|
|
{ |
|
153
|
|
|
return self::$content; |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
/** |
|
157
|
|
|
* Set the content type. |
|
158
|
|
|
* |
|
159
|
|
|
* @param string $type Content type: html, txt, xml, json. |
|
160
|
|
|
* |
|
161
|
|
|
* @return string |
|
|
|
|
|
|
162
|
|
|
*/ |
|
163
|
|
|
public static function setContentType($type = 'html', $charset = 'UTF-8') |
|
|
|
|
|
|
164
|
|
|
{ |
|
165
|
|
|
$types = [ |
|
166
|
|
|
'csv' => 'text/csv', |
|
167
|
|
|
'html' => 'text/html', |
|
168
|
|
|
'txt' => 'text/plain', |
|
169
|
|
|
'xml' => 'application/xml', |
|
170
|
|
|
'rss' => 'application/rss+xml', |
|
171
|
|
|
'json' => 'application/json', |
|
172
|
|
|
'js' => 'application/javascript', |
|
173
|
|
|
]; |
|
174
|
|
|
|
|
175
|
|
|
if (isset($types[$type]) === false) { |
|
176
|
|
|
throw new \InvalidArgumentException('Specified type not valid. Use: html, txt, xml or json.'); |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
#addHeader('Content-Type', $type . ($charset ? '; charset='.$charset.': '')); |
|
180
|
|
|
self::$content_type = $types[$type]; |
|
181
|
|
|
} |
|
182
|
|
|
|
|
183
|
|
|
/** |
|
184
|
|
|
* Returns the content type for insertion into the header. |
|
185
|
|
|
* |
|
186
|
|
|
* @return string A content type, like "application/json" or "text/html". |
|
187
|
|
|
*/ |
|
188
|
|
|
public static function getContentType() |
|
189
|
|
|
{ |
|
190
|
|
|
return self::$content_type; |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
/** |
|
194
|
|
|
* This flushes the headers and bodydata to the client. |
|
195
|
|
|
*/ |
|
196
|
|
|
public static function sendResponse() |
|
197
|
|
|
{ |
|
198
|
|
|
// save session before exit |
|
199
|
|
|
if ((bool) session_id()) { |
|
200
|
|
|
session_write_close(); |
|
201
|
|
|
} |
|
202
|
|
|
|
|
203
|
|
|
// activateOutputCompression when not in debugging mode |
|
204
|
|
|
if (defined('DEBUG') and DEBUG === false) { |
|
|
|
|
|
|
205
|
|
|
\Koch\Http\ResponseCompression::startBuffer(); |
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
|
|
// Send the status line |
|
209
|
|
|
self::addHeader('HTTP/1.1', self::$statusCode . ' ' . self::getStatusCodeDescription(self::$statusCode)); |
|
210
|
|
|
|
|
211
|
|
|
// Suppress Framesets |
|
212
|
|
|
self::addHeader('X-Frame-Options', 'deny'); // not SAMEORIGIN |
|
213
|
|
|
|
|
214
|
|
|
// Send our Content-Type with UTF-8 encoding |
|
215
|
|
|
self::addHeader('Content-Type', self::getContentType() . '; charset=UTF-8'); |
|
216
|
|
|
|
|
217
|
|
|
// Send user specificed headers from self::$headers array |
|
218
|
|
|
if (false === headers_sent()) { |
|
219
|
|
|
foreach (self::$headers as $name => $value) { |
|
220
|
|
|
header($name . ': ' . $value, false); |
|
221
|
|
|
} |
|
222
|
|
|
} |
|
223
|
|
|
|
|
224
|
|
|
// make it possible to attach HTML content to the body directly before flushing the response |
|
225
|
|
|
// \Clansuite\Application::triggerEvent('onBeforeResponse', array('content' => self::$content)); |
|
|
|
|
|
|
226
|
|
|
|
|
227
|
|
|
// Finally echo the response body |
|
228
|
|
|
echo self::getContent(); |
|
229
|
|
|
|
|
230
|
|
|
if (defined('DEBUG') and DEBUG === false) { |
|
|
|
|
|
|
231
|
|
|
\Koch\Http\ResponseCompression::flushCompressedBuffer(); |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
// OK, Reset -> Package delivered! Return to Base! |
|
235
|
|
|
self::clearHeaders(); |
|
236
|
|
|
|
|
237
|
|
|
return true; |
|
238
|
|
|
} |
|
239
|
|
|
|
|
240
|
|
|
/** |
|
241
|
|
|
* Resets the headers and content. |
|
242
|
|
|
* |
|
243
|
|
|
* @return bool true. |
|
244
|
|
|
*/ |
|
245
|
|
|
public static function clearHeaders() |
|
|
|
|
|
|
246
|
|
|
{ |
|
247
|
|
|
self::$headers = []; |
|
248
|
|
|
self::$content = null; |
|
249
|
|
|
|
|
250
|
|
|
return true; |
|
251
|
|
|
} |
|
252
|
|
|
/** |
|
253
|
|
|
* A better alternative (RFC 2109 compatible) to the php setcookie() function. |
|
254
|
|
|
* |
|
255
|
|
|
* @param string Name of the cookie |
|
256
|
|
|
* @param string Value of the cookie |
|
257
|
|
|
* @param int Lifetime of the cookie |
|
258
|
|
|
* @param string Path where the cookie can be used |
|
259
|
|
|
* @param string Domain which can read the cookie |
|
260
|
|
|
* @param bool Secure mode? |
|
261
|
|
|
* @param bool Only allow HTTP usage? (PHP 5.2) |
|
262
|
|
|
* |
|
263
|
|
|
* @return bool Cookie set. |
|
264
|
|
|
*/ |
|
265
|
|
|
public static function setCookie($name, $value = '', $maxage = 0, $path = '', $domain = '', $secure = false, $HTTPOnly = false) |
|
266
|
|
|
{ |
|
267
|
|
|
$ob = ini_get('output_buffering'); |
|
268
|
|
|
|
|
269
|
|
|
// Abort the method if headers have already been sent, except when output buffering has been enabled |
|
270
|
|
|
if (headers_sent() && (bool) $ob === false or mb_strtolower($ob) === 'off') { |
|
|
|
|
|
|
271
|
|
|
return false; |
|
272
|
|
|
} |
|
273
|
|
|
|
|
274
|
|
|
if (false === empty($domain)) { |
|
275
|
|
|
// Fix the domain to accept domains with and without 'www.'. |
|
276
|
|
|
if (mb_strtolower(mb_substr($domain, 0, 4)) === 'www.') { |
|
277
|
|
|
$domain = mb_substr($domain, 4); |
|
278
|
|
|
} |
|
279
|
|
|
|
|
280
|
|
|
// Add the dot prefix to ensure compatibility with subdomains |
|
281
|
|
|
if (mb_substr($domain, 0, 1) !== '.') { |
|
282
|
|
|
$domain = '.' . $domain; |
|
283
|
|
|
} |
|
284
|
|
|
|
|
285
|
|
|
// Remove port information. |
|
286
|
|
|
$port = mb_strpos($domain, ':'); |
|
287
|
|
|
|
|
288
|
|
|
if ($port !== false) { |
|
289
|
|
|
$domain = mb_substr($domain, 0, $port); |
|
290
|
|
|
} |
|
291
|
|
|
} |
|
292
|
|
|
|
|
293
|
|
|
header( |
|
294
|
|
|
'Set-Cookie: ' . rawurlencode($name) . '=' . rawurlencode($value) |
|
295
|
|
|
. (true === empty($domain) ? '' : '; Domain=' . $domain) |
|
296
|
|
|
. (true === empty($maxage) ? '' : '; Max-Age=' . $maxage) |
|
297
|
|
|
. (true === empty($path) ? '' : '; Path=' . $path) |
|
298
|
|
|
. (false === $secure ? '' : '; Secure') |
|
299
|
|
|
. (false === $HTTPOnly ? '' : '; HttpOnly'), |
|
|
|
|
|
|
300
|
|
|
false |
|
301
|
|
|
); |
|
302
|
|
|
|
|
303
|
|
|
return true; |
|
304
|
|
|
} |
|
305
|
|
|
|
|
306
|
|
|
/** |
|
307
|
|
|
* Deletes a cookie. |
|
308
|
|
|
* |
|
309
|
|
|
* @param string $name Name of the cookie |
|
310
|
|
|
* @param string $path Path where the cookie is used |
|
311
|
|
|
* @param string $domain Domain of the cookie |
|
312
|
|
|
* @param bool Secure mode? |
|
313
|
|
|
* @param bool Only allow HTTP usage? (PHP 5.2) |
|
314
|
|
|
*/ |
|
315
|
|
|
public static function deleteCookie($name, $path = '/', $domain = '', $secure = false, $httponly = null) |
|
316
|
|
|
{ |
|
317
|
|
|
// expire = 324993600 = 1980-04-19 |
|
318
|
|
|
setcookie($name, '', 324993600, $path, $domain, $secure, $httponly); |
|
319
|
|
|
} |
|
320
|
|
|
|
|
321
|
|
|
/** |
|
322
|
|
|
* Sets NoCache Header Values. |
|
323
|
|
|
*/ |
|
324
|
|
|
public static function setNoCacheHeader() |
|
325
|
|
|
{ |
|
326
|
|
|
// set nocache via session |
|
327
|
|
|
#session_cache_limiter('nocache'); |
|
328
|
|
|
// reset pragma header |
|
329
|
|
|
self::addHeader('Pragma', 'no-cache'); |
|
330
|
|
|
// reset cache-control |
|
331
|
|
|
self::addHeader('Cache-Control', 'no-store, no-cache, must-revalidate'); |
|
332
|
|
|
// append cache-control |
|
333
|
|
|
self::addHeader('Cache-Control', 'post-check=0, pre-check=0'); |
|
334
|
|
|
// force immediate expiration |
|
335
|
|
|
self::addHeader('Expires', '1'); |
|
336
|
|
|
// set date of last modification |
|
337
|
|
|
self::addHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT'); |
|
338
|
|
|
} |
|
339
|
|
|
|
|
340
|
|
|
/** |
|
341
|
|
|
* Detects a flashmessage tunneling via the redirect messagetext. |
|
342
|
|
|
* |
|
343
|
|
|
* @param string $message Redirect Message ("flashmessagetype#message text") |
|
344
|
|
|
*/ |
|
345
|
|
|
public static function detectTypeAndSetFlashmessage($message) |
|
|
|
|
|
|
346
|
|
|
{ |
|
347
|
|
|
// detect if a flashmessage is tunneled |
|
348
|
|
|
if ($message !== null and true === (bool) strpos($message, '#')) { |
|
|
|
|
|
|
349
|
|
|
// split at tunneling separator |
|
350
|
|
|
$array = explode('#', $message); |
|
351
|
|
|
// results in: array[0] = type and array[1] = message) |
|
|
|
|
|
|
352
|
|
|
\Koch\Session\FlashMessages::setMessage($array[0], $array[1]); |
|
353
|
|
|
// return the message |
|
354
|
|
|
return $array[1]; |
|
355
|
|
|
} |
|
356
|
|
|
} |
|
357
|
|
|
|
|
358
|
|
|
/** |
|
359
|
|
|
* Redirect. |
|
360
|
|
|
* |
|
361
|
|
|
* Redirects to another action after disabling the caching. |
|
362
|
|
|
* This avoids the typical reposting after an POST is send by disabling the cache. |
|
363
|
|
|
* This enables the POST-Redirect-GET Workflow. |
|
364
|
|
|
* |
|
365
|
|
|
* @param string Redirect to this URL |
|
366
|
|
|
* @param int seconds before redirecting (for the html tag "meta refresh") |
|
367
|
|
|
* @param int http status code, default: '303' => 'See other' |
|
368
|
|
|
* @param string redirect message |
|
369
|
|
|
*/ |
|
370
|
|
|
public static function redirectNoCache($url, $time = 0, $statusCode = 303, $message = '') |
|
371
|
|
|
{ |
|
372
|
|
|
self::setNoCacheHeader(); |
|
373
|
|
|
self::redirect($url, $time, $statusCode, $message); |
|
374
|
|
|
} |
|
375
|
|
|
|
|
376
|
|
|
/** |
|
377
|
|
|
* Redirect, redirects to an URL. |
|
378
|
|
|
* This redirects automatically, when headers are not already sent, |
|
379
|
|
|
* else it provides a link to the target URL for manual redirection. |
|
380
|
|
|
* |
|
381
|
|
|
* Time defines how long the redirect screen will be displayed. |
|
382
|
|
|
* Statuscode defines a http status code. The default value is 303. |
|
383
|
|
|
* Text is a message string for the html body of the redirect screen. |
|
384
|
|
|
* |
|
385
|
|
|
* @param string Redirect to this URL |
|
386
|
|
|
* @param int seconds before redirecting (for the html tag "meta refresh") |
|
387
|
|
|
* @param int http status code, default: '303' => 'See other' |
|
388
|
|
|
* @param text text of redirect message |
|
389
|
|
|
* @param string redirect mode LOCATION, REFRESH, JS, HTML |
|
390
|
|
|
* @param string $mode |
|
|
|
|
|
|
391
|
|
|
*/ |
|
392
|
|
|
public static function redirect($url, $time = 0, $statusCode = 303, $message = null, $mode = null) |
|
393
|
|
|
{ |
|
394
|
|
|
// convert from internal slashed format to external URL |
|
395
|
|
|
$url = \Koch\Router\Router::buildURL($url, false); |
|
396
|
|
|
|
|
397
|
|
|
$filename = ''; |
|
398
|
|
|
$linenum = ''; |
|
399
|
|
|
$redirect_html = ''; |
|
|
|
|
|
|
400
|
|
|
|
|
401
|
|
|
// redirect only, if headers are NOT already send |
|
402
|
|
|
if (headers_sent($filename, $linenum) === false) { |
|
403
|
|
|
// clear all output buffers |
|
404
|
|
|
#while(@ob_end_clean()); |
|
|
|
|
|
|
405
|
|
|
|
|
406
|
|
|
// redirect to ... |
|
407
|
|
|
self::setStatusCode($statusCode); |
|
408
|
|
|
|
|
409
|
|
|
// detect if redirect message contains a flashmessage type |
|
410
|
|
|
// fetch message from "type#message" |
|
411
|
|
|
$message = self::detectTypeAndSetFlashmessage($message); |
|
412
|
|
|
|
|
413
|
|
|
switch ($mode) { |
|
414
|
|
|
default: |
|
415
|
|
|
case 'LOCATION': |
|
416
|
|
|
header('LOCATION: ' . $url); |
|
417
|
|
|
#session_write_close(); // @todo figure out, if session closing is needed? |
|
418
|
|
|
\Koch\Tools\ApplicationQuit::quit(); |
|
419
|
|
|
break; |
|
420
|
|
|
case 'REFRESH': |
|
421
|
|
|
header('Refresh: 0; URL="' . $url . '"'); |
|
422
|
|
|
#session_write_close(); // @todo figure out, if session closing is needed? |
|
423
|
|
|
break; |
|
424
|
|
|
case 'JS': |
|
425
|
|
|
$redirect_html = '<script type="text/javascript">window.location.href=' . $url . ';</script>'; |
|
|
|
|
|
|
426
|
|
|
break; |
|
427
|
|
|
case 'HTML': |
|
428
|
|
|
// redirect html content |
|
429
|
|
|
$redirect_html = '<html><head>'; |
|
|
|
|
|
|
430
|
|
|
$redirect_html .= '<meta http-equiv="refresh" content="' . $time . '; URL=' . $url . '" />'; |
|
|
|
|
|
|
431
|
|
|
$redirect_html .= '</head><body>' . $message . '</body></html>'; |
|
|
|
|
|
|
432
|
|
|
break; |
|
433
|
|
|
} |
|
434
|
|
|
|
|
435
|
|
|
if (empty($redirect_html) === false) { |
|
|
|
|
|
|
436
|
|
|
#self::addHeader('Location', $url); |
|
|
|
|
|
|
437
|
|
|
self::setContent($redirect_html, $time, htmlspecialchars($url, ENT_QUOTES, 'UTF-8')); |
|
|
|
|
|
|
438
|
|
|
} |
|
439
|
|
|
|
|
440
|
|
|
// Flush the content on the normal way! |
|
441
|
|
|
self::sendResponse(); |
|
442
|
|
|
} else { // headers already send! |
|
443
|
|
|
$msg = _('Header already send in file %s in line %s. Redirecting impossible.'); |
|
444
|
|
|
$msg .= _('You might click this link instead to redirect yourself to the <a href="%s">target url</a> an'); |
|
445
|
|
|
sprintf($msg, $filename, $linenum, $url); |
|
446
|
|
|
\Koch\Tools\ApplicationQuit::quit(); |
|
447
|
|
|
} |
|
448
|
|
|
} |
|
449
|
|
|
} |
|
450
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.