1 | <?php |
||||||
2 | |||||||
3 | /** |
||||||
4 | * THttpSession class |
||||||
5 | * |
||||||
6 | * @author Qiang Xue <[email protected]> |
||||||
7 | * @link https://github.com/pradosoft/prado |
||||||
8 | * @license https://github.com/pradosoft/prado/blob/master/LICENSE |
||||||
9 | */ |
||||||
10 | |||||||
11 | namespace Prado\Web; |
||||||
12 | |||||||
13 | use Prado\Exceptions\TInvalidDataValueException; |
||||||
14 | use Prado\Exceptions\TInvalidOperationException; |
||||||
15 | use Prado\TPropertyValue; |
||||||
16 | use Prado\Prado; |
||||||
17 | |||||||
18 | /** |
||||||
19 | * THttpSession class |
||||||
20 | * |
||||||
21 | * THttpSession provides session-level data management and the related configurations. |
||||||
22 | * To start the session, call {@see open}; to complete and send out session data, call {@see close}; |
||||||
23 | * to destroy the session, call {@see destroy}. If AutoStart is true, then the session |
||||||
24 | * will be started once the session module is loaded and initialized. |
||||||
25 | * |
||||||
26 | * To access data stored in session, use THttpSession like an associative array. For example, |
||||||
27 | * ```php |
||||||
28 | * $session=new THttpSession; |
||||||
29 | * $session->open(); |
||||||
30 | * $value1=$session['name1']; // get session variable 'name1' |
||||||
31 | * $value2=$session['name2']; // get session variable 'name2' |
||||||
32 | * foreach($session as $name=>$value) // traverse all session variables |
||||||
33 | * $session['name3']=$value3; // set session variable 'name3' |
||||||
34 | * ``` |
||||||
35 | * |
||||||
36 | * The following configurations are available for session: |
||||||
37 | * {@see setAutoStart AutoStart}, {@see setCookieMode CookieMode}, |
||||||
38 | * {@see setSavePath SavePath}, |
||||||
39 | * {@see setUseCustomStorage UseCustomStorage}, {@see setGCProbability GCProbability}, |
||||||
40 | * {@see setTimeout Timeout}. |
||||||
41 | * See the corresponding setter and getter documentation for more information. |
||||||
42 | * Note, these properties must be set before the session is started. |
||||||
43 | * |
||||||
44 | * THttpSession can be inherited with customized session storage method. |
||||||
45 | * Override {@see _open}, {@see _close}, {@see _read}, {@see _write}, {@see _destroy} and {@see _gc} |
||||||
46 | * and set {@see setUseCustomStorage UseCustomStorage} to true. |
||||||
47 | * Then, the session data will be stored using the above methods. |
||||||
48 | * |
||||||
49 | * By default, THttpSession is registered with {@see \Prado\TApplication} as the |
||||||
50 | * request module. It can be accessed via {@see \Prado\TApplication::getSession()}. |
||||||
51 | * |
||||||
52 | * THttpSession may be configured in application configuration file as follows, |
||||||
53 | * ```xml |
||||||
54 | * <module id="session" class="THttpSession" SessionName="SSID" SavePath="/tmp" |
||||||
55 | * CookieMode="Allow" UseCustomStorage="false" AutoStart="true" GCProbability="1" |
||||||
56 | * UseTransparentSessionID="true" TimeOut="3600" /> |
||||||
57 | * ``` |
||||||
58 | * where {@see getSessionName SessionName}, {@see getSavePath SavePath}, |
||||||
59 | * {@see getCookieMode CookieMode}, {@see getUseCustomStorage |
||||||
60 | * UseCustomStorage}, {@see getAutoStart AutoStart}, {@see getGCProbability |
||||||
61 | * GCProbability}, {@see getUseTransparentSessionID UseTransparentSessionID} |
||||||
62 | * and {@see getTimeout TimeOut} are configurable properties of THttpSession. |
||||||
63 | * |
||||||
64 | * To avoid the possibility of identity theft through some variants of XSS attacks, |
||||||
65 | * THttpSessionshould always be configured to enforce HttpOnly setting on session cookie. |
||||||
66 | * The HttpOnly setting is disabled by default. To enable it, configure the THttpSession |
||||||
67 | * module as follows, |
||||||
68 | * ```xml |
||||||
69 | * <module id="session" class="THttpSession" Cookie.HttpOnly="true" > |
||||||
70 | * ``` |
||||||
71 | * |
||||||
72 | * @author Qiang Xue <[email protected]> |
||||||
73 | * @since 3.0 |
||||||
74 | */ |
||||||
75 | class THttpSession extends \Prado\TApplicationComponent implements \IteratorAggregate, \ArrayAccess, \Countable, \Prado\IModule |
||||||
76 | { |
||||||
77 | /** |
||||||
78 | * @var bool whether this module has been initialized |
||||||
79 | */ |
||||||
80 | private $_initialized = false; |
||||||
81 | /** |
||||||
82 | * @var bool whether the session has started |
||||||
83 | */ |
||||||
84 | private $_started = false; |
||||||
85 | /** |
||||||
86 | * @var bool whether the session should be started when the module is initialized |
||||||
87 | */ |
||||||
88 | private $_autoStart = false; |
||||||
89 | /** |
||||||
90 | * @var THttpCookie cookie to be used to store session ID and other data |
||||||
91 | */ |
||||||
92 | private $_cookie; |
||||||
93 | /** |
||||||
94 | * @var string module id |
||||||
95 | */ |
||||||
96 | private $_id; |
||||||
97 | /** |
||||||
98 | * @var bool |
||||||
99 | */ |
||||||
100 | private $_customStorage = false; |
||||||
101 | |||||||
102 | /** |
||||||
103 | * @return string id of this module |
||||||
104 | */ |
||||||
105 | public function getID() |
||||||
106 | { |
||||||
107 | return $this->_id; |
||||||
108 | } |
||||||
109 | |||||||
110 | /** |
||||||
111 | * @param string $value id of this module |
||||||
112 | */ |
||||||
113 | public function setID($value) |
||||||
114 | { |
||||||
115 | $this->_id = $value; |
||||||
116 | } |
||||||
117 | |||||||
118 | /** |
||||||
119 | * Initializes the module. |
||||||
120 | * This method is required by IModule. |
||||||
121 | * If AutoStart is true, the session will be started. |
||||||
122 | * @param \Prado\Xml\TXmlElement $config module configuration |
||||||
123 | */ |
||||||
124 | public function init($config) |
||||||
125 | 10 | { |
|||||
126 | if ($this->_autoStart) { |
||||||
127 | 10 | $this->open(); |
|||||
128 | } |
||||||
129 | $this->_initialized = true; |
||||||
130 | 10 | $this->getApplication()->setSession($this); |
|||||
131 | 10 | register_shutdown_function([$this, "close"]); |
|||||
132 | 10 | } |
|||||
133 | 10 | ||||||
134 | /** |
||||||
135 | * Starts the session if it has not started yet. |
||||||
136 | */ |
||||||
137 | public function open() |
||||||
138 | { |
||||||
139 | if (!$this->_started) { |
||||||
140 | if ($this->_customStorage) { |
||||||
141 | $handler = new THttpSessionHandler($this); |
||||||
142 | session_set_save_handler($handler); |
||||||
143 | } |
||||||
144 | if ($this->_cookie !== null) { |
||||||
145 | session_set_cookie_params($this->_cookie->getPhpOptions('lifetime')); |
||||||
146 | } |
||||||
147 | if (ini_get('session.auto_start') !== '1') { |
||||||
148 | session_start(); |
||||||
149 | } |
||||||
150 | $this->_started = true; |
||||||
151 | } |
||||||
152 | } |
||||||
153 | |||||||
154 | /** |
||||||
155 | * Ends the current session and store session data. |
||||||
156 | */ |
||||||
157 | public function close() |
||||||
158 | { |
||||||
159 | if ($this->_started) { |
||||||
160 | session_write_close(); |
||||||
161 | $this->_started = false; |
||||||
162 | } |
||||||
163 | } |
||||||
164 | |||||||
165 | /** |
||||||
166 | * Destroys all data registered to a session. |
||||||
167 | */ |
||||||
168 | 1 | public function destroy() |
|||||
169 | { |
||||||
170 | 1 | if ($this->_started) { |
|||||
171 | session_destroy(); |
||||||
172 | $this->_started = false; |
||||||
173 | } |
||||||
174 | 1 | } |
|||||
175 | |||||||
176 | /** |
||||||
177 | * Update the current session id with a newly generated one |
||||||
178 | * |
||||||
179 | * @param bool $deleteOld Whether to delete the old associated session or not. |
||||||
180 | * @return string old session id |
||||||
181 | * @link http://php.net/manual/en/function.session-regenerate-id.php |
||||||
182 | */ |
||||||
183 | public function regenerate($deleteOld = false) |
||||||
184 | { |
||||||
185 | $old = $this->getSessionID(); |
||||||
186 | session_regenerate_id($deleteOld); |
||||||
187 | return $old; |
||||||
188 | } |
||||||
189 | |||||||
190 | /** |
||||||
191 | * @return bool whether the session has started |
||||||
192 | */ |
||||||
193 | 1 | public function getIsStarted() |
|||||
194 | { |
||||||
195 | 1 | return $this->_started; |
|||||
196 | } |
||||||
197 | |||||||
198 | /** |
||||||
199 | * @return string the current session ID |
||||||
200 | */ |
||||||
201 | public function getSessionID() |
||||||
202 | { |
||||||
203 | return session_id(); |
||||||
204 | } |
||||||
205 | |||||||
206 | /** |
||||||
207 | * @param string $value the session ID for the current session |
||||||
208 | * @throws TInvalidOperationException if session is started already |
||||||
209 | */ |
||||||
210 | public function setSessionID($value) |
||||||
211 | { |
||||||
212 | if ($this->_started) { |
||||||
213 | throw new TInvalidOperationException('httpsession_sessionid_unchangeable'); |
||||||
214 | } else { |
||||||
215 | session_id($value); |
||||||
216 | } |
||||||
217 | } |
||||||
218 | |||||||
219 | /** |
||||||
220 | * @return string the current session name |
||||||
221 | */ |
||||||
222 | public function getSessionName() |
||||||
223 | { |
||||||
224 | return session_name(); |
||||||
225 | } |
||||||
226 | |||||||
227 | /** |
||||||
228 | * @param string $value the session name for the current session, must be an alphanumeric string, defaults to PHPSESSID |
||||||
229 | * @throws TInvalidOperationException if session is started already |
||||||
230 | */ |
||||||
231 | public function setSessionName($value) |
||||||
232 | { |
||||||
233 | if ($this->_started) { |
||||||
234 | throw new TInvalidOperationException('httpsession_sessionname_unchangeable'); |
||||||
235 | } elseif (ctype_alnum($value)) { |
||||||
236 | session_name($value); |
||||||
237 | } else { |
||||||
238 | throw new TInvalidDataValueException('httpsession_sessionname_invalid', $value); |
||||||
239 | } |
||||||
240 | } |
||||||
241 | |||||||
242 | /** |
||||||
243 | * @return string the current session save path, defaults to '/tmp'. |
||||||
244 | */ |
||||||
245 | public function getSavePath() |
||||||
246 | { |
||||||
247 | return session_save_path(); |
||||||
248 | } |
||||||
249 | |||||||
250 | /** |
||||||
251 | * @param string $value the current session save path |
||||||
252 | * @throws TInvalidOperationException if session is started already |
||||||
253 | */ |
||||||
254 | public function setSavePath($value) |
||||||
255 | { |
||||||
256 | if ($this->_started) { |
||||||
257 | throw new TInvalidOperationException('httpsession_savepath_unchangeable'); |
||||||
258 | } elseif (is_dir($value)) { |
||||||
259 | session_save_path(realpath($value)); |
||||||
260 | } elseif (null !== ($ns = Prado::getPathOfNamespace($value)) && is_dir($ns)) { |
||||||
261 | session_save_path(realpath($ns)); |
||||||
262 | } else { |
||||||
263 | throw new TInvalidDataValueException('httpsession_savepath_invalid', $value); |
||||||
264 | } |
||||||
265 | } |
||||||
266 | |||||||
267 | /** |
||||||
268 | * @return bool whether to use user-specified handlers to store session data. Defaults to false. |
||||||
269 | */ |
||||||
270 | public function getUseCustomStorage() |
||||||
271 | { |
||||||
272 | return $this->_customStorage; |
||||||
273 | } |
||||||
274 | |||||||
275 | /** |
||||||
276 | * @param bool $value whether to use user-specified handlers to store session data. |
||||||
277 | * If true, make sure the methods {@see _open}, {@see _close}, {@see _read}, |
||||||
278 | * {@see _write}, {@see _destroy}, and {@see _gc} are overridden in child |
||||||
279 | * class, because they will be used as the callback handlers. |
||||||
280 | */ |
||||||
281 | 10 | public function setUseCustomStorage($value) |
|||||
282 | { |
||||||
283 | 10 | $this->_customStorage = TPropertyValue::ensureBoolean($value); |
|||||
284 | 10 | } |
|||||
285 | |||||||
286 | /** |
||||||
287 | * @return THttpCookie cookie that will be used to store session ID |
||||||
288 | */ |
||||||
289 | public function getCookie() |
||||||
290 | { |
||||||
291 | if ($this->_cookie === null) { |
||||||
292 | $this->_cookie = new THttpCookie($this->getSessionName(), $this->getSessionID()); |
||||||
293 | } |
||||||
294 | return $this->_cookie; |
||||||
295 | } |
||||||
296 | |||||||
297 | /** |
||||||
298 | * @return THttpSessionCookieMode how to use cookie to store session ID. Defaults to THttpSessionCookieMode::Allow. |
||||||
299 | */ |
||||||
300 | 3 | public function getCookieMode() |
|||||
301 | { |
||||||
302 | 3 | if (ini_get('session.use_cookies') === '0') { |
|||||
303 | 1 | return THttpSessionCookieMode::None; |
|||||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() The constant
Prado\Web\THttpSessionCookieMode::None has been deprecated: 4.3.1 Since PHP 8.4 disabling session.use_only_cookies INI setting is deprecated; use THttpSessionCookieMode::Only instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This class constant has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead. ![]() |
|||||||
304 | 2 | } elseif (ini_get('session.use_only_cookies') === '0') { |
|||||
305 | 1 | return THttpSessionCookieMode::Allow; |
|||||
0 ignored issues
–
show
The constant
Prado\Web\THttpSessionCookieMode::Allow has been deprecated: 4.3.1 Since PHP 8.4 disabling session.use_only_cookies INI setting is deprecated; use THttpSessionCookieMode::Only instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This class constant has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead. ![]() |
|||||||
306 | } else { |
||||||
307 | 1 | return THttpSessionCookieMode::Only; |
|||||
0 ignored issues
–
show
|
|||||||
308 | } |
||||||
309 | } |
||||||
310 | |||||||
311 | /** |
||||||
312 | * @param THttpSessionCookieMode $value how to use cookie to store session ID |
||||||
313 | * @throws TInvalidOperationException if session is started already |
||||||
314 | * @deprecated 4.3.1 Since PHP 8.4 disabling session.use_only_cookies |
||||||
315 | 3 | * INI setting is deprecated; Only THttpSessionCookieMode::Only is supported. |
|||||
316 | */ |
||||||
317 | 3 | public function setCookieMode($value) |
|||||
318 | { |
||||||
319 | if ($this->_started) { |
||||||
320 | 3 | throw new TInvalidOperationException('httpsession_cookiemode_unchangeable'); |
|||||
321 | 3 | } else { |
|||||
322 | 1 | $value = TPropertyValue::ensureEnum($value, THttpSessionCookieMode::class); |
|||||
323 | 1 | if ($value === THttpSessionCookieMode::None) { |
|||||
0 ignored issues
–
show
The constant
Prado\Web\THttpSessionCookieMode::None has been deprecated: 4.3.1 Since PHP 8.4 disabling session.use_only_cookies INI setting is deprecated; use THttpSessionCookieMode::Only instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This class constant has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead. ![]() |
|||||||
324 | 2 | ini_set('session.use_cookies', '0'); |
|||||
325 | 1 | ini_set('session.use_only_cookies', '0'); |
|||||
326 | 1 | } elseif ($value === THttpSessionCookieMode::Allow) { |
|||||
0 ignored issues
–
show
The constant
Prado\Web\THttpSessionCookieMode::Allow has been deprecated: 4.3.1 Since PHP 8.4 disabling session.use_only_cookies INI setting is deprecated; use THttpSessionCookieMode::Only instead.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This class constant has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead. ![]() |
|||||||
327 | ini_set('session.use_cookies', '1'); |
||||||
328 | 1 | ini_set('session.use_only_cookies', '0'); |
|||||
329 | 1 | } else { |
|||||
330 | 1 | ini_set('session.use_cookies', '1'); |
|||||
331 | ini_set('session.use_only_cookies', '1'); |
||||||
332 | ini_set('session.use_trans_sid', 0); |
||||||
333 | 3 | } |
|||||
334 | } |
||||||
335 | } |
||||||
336 | |||||||
337 | /** |
||||||
338 | * @return bool whether the session should be automatically started when the session module is initialized, defaults to false. |
||||||
339 | */ |
||||||
340 | public function getAutoStart() |
||||||
341 | { |
||||||
342 | return $this->_autoStart; |
||||||
343 | } |
||||||
344 | |||||||
345 | /** |
||||||
346 | * @param bool $value whether the session should be automatically started when the session module is initialized, defaults to false. |
||||||
347 | * @throws TInvalidOperationException if session is started already |
||||||
348 | */ |
||||||
349 | public function setAutoStart($value) |
||||||
350 | { |
||||||
351 | if ($this->_initialized) { |
||||||
352 | throw new TInvalidOperationException('httpsession_autostart_unchangeable'); |
||||||
353 | } else { |
||||||
354 | $this->_autoStart = TPropertyValue::ensureBoolean($value); |
||||||
355 | } |
||||||
356 | } |
||||||
357 | |||||||
358 | /** |
||||||
359 | * @return int the probability (percentage) that the gc (garbage collection) process is started on every session initialization, defaults to 1 meaning 1% chance. |
||||||
360 | */ |
||||||
361 | public function getGCProbability() |
||||||
362 | { |
||||||
363 | return TPropertyValue::ensureInteger(ini_get('session.gc_probability')); |
||||||
364 | } |
||||||
365 | |||||||
366 | /** |
||||||
367 | * @param int $value the probability (percentage) that the gc (garbage collection) process is started on every session initialization. |
||||||
368 | * @throws TInvalidOperationException if session is started already |
||||||
369 | * @throws TInvalidDataValueException if the value is beyond [0,100]. |
||||||
370 | */ |
||||||
371 | public function setGCProbability($value) |
||||||
372 | { |
||||||
373 | if ($this->_started) { |
||||||
374 | throw new TInvalidOperationException('httpsession_gcprobability_unchangeable'); |
||||||
375 | } else { |
||||||
376 | $value = TPropertyValue::ensureInteger($value); |
||||||
377 | if ($value >= 0 && $value <= 100) { |
||||||
378 | ini_set('session.gc_probability', $value); |
||||||
379 | ini_set('session.gc_divisor', '100'); |
||||||
380 | } else { |
||||||
381 | throw new TInvalidDataValueException('httpsession_gcprobability_invalid', $value); |
||||||
382 | } |
||||||
383 | } |
||||||
384 | } |
||||||
385 | |||||||
386 | /** |
||||||
387 | * @return bool whether transparent sid support is enabled or not, defaults to false. |
||||||
388 | */ |
||||||
389 | public function getUseTransparentSessionID() |
||||||
390 | { |
||||||
391 | return ini_get('session.use_trans_sid') === '1'; |
||||||
392 | } |
||||||
393 | |||||||
394 | /** |
||||||
395 | * Ensure that {@see setCookieMode CookieMode} is not set to "None" before enabling |
||||||
396 | * the use of transparent session ids. Refer to the main documentation of the class |
||||||
397 | * THttpSession class for a configuration example. |
||||||
398 | * |
||||||
399 | * @param bool $value whether transparent sid support is enabled or not. |
||||||
400 | */ |
||||||
401 | public function setUseTransparentSessionID($value) |
||||||
402 | { |
||||||
403 | if ($this->_started) { |
||||||
404 | throw new TInvalidOperationException('httpsession_transid_unchangeable'); |
||||||
405 | } else { |
||||||
406 | $value = TPropertyValue::ensureBoolean($value); |
||||||
407 | if ($value && $this->getCookieMode() == THttpSessionCookieMode::Only) { |
||||||
0 ignored issues
–
show
|
|||||||
408 | throw new TInvalidOperationException('httpsession_transid_cookieonly'); |
||||||
409 | } |
||||||
410 | ini_set('session.use_trans_sid', $value ? '1' : '0'); |
||||||
411 | } |
||||||
412 | } |
||||||
413 | |||||||
414 | /** |
||||||
415 | * @return int the number of seconds after which data will be seen as 'garbage' and cleaned up, defaults to 1440 seconds. |
||||||
416 | */ |
||||||
417 | public function getTimeout() |
||||||
418 | { |
||||||
419 | return TPropertyValue::ensureInteger(ini_get('session.gc_maxlifetime')); |
||||||
420 | } |
||||||
421 | |||||||
422 | /** |
||||||
423 | * @param int $value the number of seconds after which data will be seen as 'garbage' and cleaned up |
||||||
424 | * @throws TInvalidOperationException if session is started already |
||||||
425 | */ |
||||||
426 | public function setTimeout($value) |
||||||
427 | { |
||||||
428 | if ($this->_started) { |
||||||
429 | throw new TInvalidOperationException('httpsession_maxlifetime_unchangeable'); |
||||||
430 | } else { |
||||||
431 | ini_set('session.gc_maxlifetime', $value); |
||||||
432 | } |
||||||
433 | } |
||||||
434 | |||||||
435 | /** |
||||||
436 | * Session open handler. |
||||||
437 | * This method should be overridden if {@see setUseCustomStorage UseCustomStorage} is set true. |
||||||
438 | * @param string $savePath session save path |
||||||
439 | * @param string $sessionName session name |
||||||
440 | * @return bool whether session is opened successfully |
||||||
441 | */ |
||||||
442 | public function _open($savePath, $sessionName) |
||||||
0 ignored issues
–
show
The parameter
$savePath is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() The parameter
$sessionName is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
443 | { |
||||||
444 | return true; |
||||||
445 | } |
||||||
446 | |||||||
447 | /** |
||||||
448 | * Session close handler. |
||||||
449 | * This method should be overridden if {@see setUseCustomStorage UseCustomStorage} is set true. |
||||||
450 | * @return bool whether session is closed successfully |
||||||
451 | */ |
||||||
452 | public function _close() |
||||||
453 | { |
||||||
454 | return true; |
||||||
455 | } |
||||||
456 | |||||||
457 | /** |
||||||
458 | * Session read handler. |
||||||
459 | * This method should be overridden if {@see setUseCustomStorage UseCustomStorage} is set true. |
||||||
460 | * @param string $id session ID |
||||||
461 | * @return string the session data |
||||||
462 | */ |
||||||
463 | public function _read($id) |
||||||
0 ignored issues
–
show
The parameter
$id is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
464 | { |
||||||
465 | return ''; |
||||||
466 | } |
||||||
467 | |||||||
468 | /** |
||||||
469 | * Session write handler. |
||||||
470 | * This method should be overridden if {@see setUseCustomStorage UseCustomStorage} is set true. |
||||||
471 | * @param string $id session ID |
||||||
472 | * @param string $data session data |
||||||
473 | * @return bool whether session write is successful |
||||||
474 | */ |
||||||
475 | public function _write($id, $data) |
||||||
0 ignored issues
–
show
The parameter
$data is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() The parameter
$id is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
476 | { |
||||||
477 | return true; |
||||||
478 | } |
||||||
479 | |||||||
480 | /** |
||||||
481 | * Session destroy handler. |
||||||
482 | * This method should be overridden if {@see setUseCustomStorage UseCustomStorage} is set true. |
||||||
483 | * @param string $id session ID |
||||||
484 | * @return bool whether session is destroyed successfully |
||||||
485 | */ |
||||||
486 | public function _destroy($id) |
||||||
0 ignored issues
–
show
The parameter
$id is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
487 | { |
||||||
488 | return true; |
||||||
489 | } |
||||||
490 | |||||||
491 | /** |
||||||
492 | * Session GC (garbage collection) handler. |
||||||
493 | * This method should be overridden if {@see setUseCustomStorage UseCustomStorage} is set true. |
||||||
494 | * @param int $maxLifetime the number of seconds after which data will be seen as 'garbage' and cleaned up. |
||||||
495 | * @return bool whether session is GCed successfully |
||||||
496 | */ |
||||||
497 | public function _gc($maxLifetime) |
||||||
0 ignored issues
–
show
The parameter
$maxLifetime is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
498 | { |
||||||
499 | return true; |
||||||
500 | } |
||||||
501 | |||||||
502 | //------ The following methods enable THttpSession to be TMap-like ----- |
||||||
503 | |||||||
504 | /** |
||||||
505 | * Returns an iterator for traversing the session variables. |
||||||
506 | * This method is required by the interface \IteratorAggregate. |
||||||
507 | * @return TSessionIterator an iterator for traversing the session variables. |
||||||
508 | */ |
||||||
509 | #[\ReturnTypeWillChange] |
||||||
510 | public function getIterator() |
||||||
511 | { |
||||||
512 | return new TSessionIterator(); |
||||||
513 | } |
||||||
514 | |||||||
515 | /** |
||||||
516 | * @return int the number of session variables |
||||||
517 | */ |
||||||
518 | public function getCount() |
||||||
519 | { |
||||||
520 | return count($_SESSION); |
||||||
521 | } |
||||||
522 | |||||||
523 | /** |
||||||
524 | * Returns the number of items in the session. |
||||||
525 | * This method is required by \Countable interface. |
||||||
526 | * @return int number of items in the session. |
||||||
527 | */ |
||||||
528 | public function count(): int |
||||||
529 | { |
||||||
530 | return $this->getCount(); |
||||||
531 | } |
||||||
532 | |||||||
533 | /** |
||||||
534 | * @return array the list of session variable names |
||||||
535 | */ |
||||||
536 | public function getKeys() |
||||||
537 | { |
||||||
538 | return array_keys($_SESSION); |
||||||
539 | } |
||||||
540 | |||||||
541 | /** |
||||||
542 | * Returns the session variable value with the session variable name. |
||||||
543 | * This method is exactly the same as {@see offsetGet}. |
||||||
544 | * @param mixed $key the session variable name |
||||||
545 | * @return mixed the session variable value, null if no such variable exists |
||||||
546 | */ |
||||||
547 | public function itemAt($key) |
||||||
548 | { |
||||||
549 | return $_SESSION[$key] ?? null; |
||||||
550 | } |
||||||
551 | |||||||
552 | /** |
||||||
553 | * Adds a session variable. |
||||||
554 | * Note, if the specified name already exists, the old value will be removed first. |
||||||
555 | 1 | * @param mixed $key session variable name |
|||||
556 | * @param mixed $value session variable value |
||||||
557 | 1 | */ |
|||||
558 | 1 | public function add($key, $value) |
|||||
559 | { |
||||||
560 | $_SESSION[$key] = $value; |
||||||
561 | } |
||||||
562 | |||||||
563 | /** |
||||||
564 | * Removes a session variable. |
||||||
565 | 1 | * @param mixed $key the name of the session variable to be removed |
|||||
566 | * @return mixed the removed value, null if no such session variable. |
||||||
567 | 1 | */ |
|||||
568 | 1 | public function remove($key) |
|||||
569 | 1 | { |
|||||
570 | 1 | if (isset($_SESSION[$key])) { |
|||||
571 | $value = $_SESSION[$key]; |
||||||
572 | unset($_SESSION[$key]); |
||||||
573 | return $value; |
||||||
574 | } else { |
||||||
575 | return null; |
||||||
576 | } |
||||||
577 | } |
||||||
578 | |||||||
579 | /** |
||||||
580 | * Removes all session variables |
||||||
581 | */ |
||||||
582 | public function clear() |
||||||
583 | { |
||||||
584 | foreach (array_keys($_SESSION) as $key) { |
||||||
585 | unset($_SESSION[$key]); |
||||||
586 | } |
||||||
587 | } |
||||||
588 | |||||||
589 | /** |
||||||
590 | * @param mixed $key session variable name |
||||||
591 | * @return bool whether there is the named session variable |
||||||
592 | */ |
||||||
593 | public function contains($key) |
||||||
594 | { |
||||||
595 | return isset($_SESSION[$key]); |
||||||
596 | } |
||||||
597 | |||||||
598 | /** |
||||||
599 | * @return array the list of all session variables in array |
||||||
600 | */ |
||||||
601 | public function toArray() |
||||||
602 | { |
||||||
603 | return $_SESSION; |
||||||
604 | } |
||||||
605 | |||||||
606 | /** |
||||||
607 | * This method is required by the interface \ArrayAccess. |
||||||
608 | * @param mixed $offset the offset to check on |
||||||
609 | * @return bool |
||||||
610 | */ |
||||||
611 | public function offsetExists($offset): bool |
||||||
612 | { |
||||||
613 | return isset($_SESSION[$offset]); |
||||||
614 | } |
||||||
615 | |||||||
616 | /** |
||||||
617 | * This method is required by the interface \ArrayAccess. |
||||||
618 | 4 | * @param int $offset the offset to retrieve element. |
|||||
619 | * @return mixed the element at the offset, null if no element is found at the offset |
||||||
620 | 4 | */ |
|||||
621 | #[\ReturnTypeWillChange] |
||||||
622 | public function offsetGet($offset) |
||||||
623 | { |
||||||
624 | return $_SESSION[$offset] ?? null; |
||||||
625 | } |
||||||
626 | |||||||
627 | /** |
||||||
628 | 2 | * This method is required by the interface \ArrayAccess. |
|||||
629 | * @param int $offset the offset to set element |
||||||
630 | 2 | * @param mixed $item the element value |
|||||
631 | 2 | */ |
|||||
632 | public function offsetSet($offset, $item): void |
||||||
633 | { |
||||||
634 | $_SESSION[$offset] = $item; |
||||||
635 | } |
||||||
636 | |||||||
637 | /** |
||||||
638 | * This method is required by the interface \ArrayAccess. |
||||||
639 | * @param mixed $offset the offset to unset element |
||||||
640 | */ |
||||||
641 | public function offsetUnset($offset): void |
||||||
642 | { |
||||||
643 | unset($_SESSION[$offset]); |
||||||
644 | } |
||||||
645 | } |
||||||
646 |