@@ -21,7 +21,7 @@ interface Session
2121{
2222
2323 /**
24- * The time session has started for the last request .
24+ * The timestamp when session started.
2525 */
2626 const STAMP = '_stamp ' ;
2727
@@ -31,7 +31,7 @@ interface Session
3131 const AGENT = '_agent ' ;
3232
3333 /**
34- * CSRF token
34+ * Session token (useful for CSRF)
3535 */
3636 const TOKEN = '_token ' ;
3737
@@ -62,8 +62,24 @@ public function toData(): Data;
6262
6363 public function clear (): bool ;
6464
65+ /**
66+ * Destroys all of the data associated with the current session,
67+ * by closing the session and re-opening it again.
68+ * Also the object state is cleaned and internal metadata is recreated.
69+ *
70+ * @return bool TRUE on success, FALSE otherwise
71+ */
6572 public function destroy (): bool ;
6673
74+ /**
75+ * Update the current session id with a newly generated one
76+ * and session token with a new v4 UUID.
77+ *
78+ * @param bool $deleteOldSession [optional] Whether to delete the old associated session or not
79+ *
80+ * @return bool TRUE on success, FALSE otherwise
81+ * @link https://php.net/manual/en/function.session-regenerate-id.php
82+ */
6783 public function regenerate (bool $ deleteOldSession = false ): bool ;
6884
6985 /**
@@ -83,7 +99,7 @@ public function modified(): bool;
8399
84100 public function token (): string ;
85101
86- public function starttime (): int ;
102+ public function starttime (): float ;
87103
88104 public function agent (): string ;
89105
@@ -126,24 +142,19 @@ final class PhpSession implements Session
126142
127143 public function __construct ()
128144 {
145+ // @codeCoverageIgnoreStart
129146 if (false === isset ($ _SESSION )) {
130147 global $ _SESSION ;
131148 $ _SESSION = [];
132149 }
150+ // @codeCoverageIgnoreEnd
133151
134152 $ this ->loadMetadata ();
135153 $ this ->accessed = false ;
136154 $ this ->modified = false ;
137155 session ($ this );
138156 }
139157
140- public function __destruct ()
141- {
142- $ _SESSION [self ::STAMP ] = $ this ->stamp ;
143- $ _SESSION [self ::AGENT ] = $ this ->agent ;
144- $ _SESSION [self ::TOKEN ] = $ this ->token ;
145- }
146-
147158 public function get (string $ name , $ default = null )
148159 {
149160 $ this ->accessed = true ;
@@ -249,13 +260,6 @@ public function has(string $name): bool
249260 *
250261 */
251262
252- /**
253- * Exchange the session data for another one.
254- *
255- * @param array $data The new array or object to exchange with the current session data
256- *
257- * @return array The old session data
258- */
259263 public function replace (array $ data ): array
260264 {
261265 $ oldSession = $ _SESSION ;
@@ -275,13 +279,23 @@ public function clear(): bool
275279
276280 public function regenerate (bool $ deleteOldSession = false ): bool
277281 {
282+ $ _SESSION [self ::TOKEN ] = $ this ->token = UUID ::v4 ();
283+
278284 return session_regenerate_id ($ deleteOldSession );
279285 }
280286
281287 public function destroy (): bool
282288 {
283- // FIXME
289+ session_write_close ();
290+
291+ // @codeCoverageIgnoreStart
292+ if (false === session_start ()) {
293+ return false ;
294+ }
295+ // @codeCoverageIgnoreEnd
296+
284297 $ updated = session_regenerate_id (true );
298+
285299 $ this ->replace ([]);
286300 $ this ->resetMetadata ();
287301
@@ -308,7 +322,7 @@ public function token(): string
308322 return $ this ->token ;
309323 }
310324
311- public function starttime (): int
325+ public function starttime (): float
312326 {
313327 return $ this ->stamp ;
314328 }
@@ -339,16 +353,16 @@ public function count(): int
339353 */
340354 private function loadMetadata (): void
341355 {
342- $ this ->stamp = $ this ->pull (self ::STAMP , time ( ));
356+ $ this ->stamp = $ this ->pull (self ::STAMP , microtime ( true ));
343357 $ this ->agent = $ this ->pull (self ::AGENT , $ _SERVER ['HTTP_USER_AGENT ' ] ?? '' );
344358 $ this ->token = $ this ->pull (self ::TOKEN , UUID ::v4 ());
345359 }
346360
347361 private function resetMetadata (): void
348362 {
349- $ _SESSION [self ::STAMP ] = time ( );
350- $ _SESSION [self ::AGENT ] = $ _SERVER ['HTTP_USER_AGENT ' ] ?? '' ;
351- $ _SESSION [self ::TOKEN ] = UUID ::v4 ();
363+ $ _SESSION [self ::STAMP ] = $ this -> stamp = microtime ( true );
364+ $ _SESSION [self ::AGENT ] = $ this -> agent = $ _SERVER ['HTTP_USER_AGENT ' ] ?? '' ;
365+ $ _SESSION [self ::TOKEN ] = $ this -> token = UUID ::v4 ();
352366 }
353367
354368 private function getMetadata (): array
0 commit comments