@@ -180,10 +180,21 @@ public function start()
180
180
// Need to apply the config options so they can be ready by session_start
181
181
$ this ->initIniOptions ();
182
182
$ this ->registerSaveHandler ();
183
+ if (isset ($ _SESSION ['new_session_id ' ])) {
184
+ // Not fully expired yet. Could be lost cookie by unstable network.
185
+ session_commit ();
186
+ session_id ($ _SESSION ['new_session_id ' ]);
187
+ }
183
188
$ sid = $ this ->sidResolver ->getSid ($ this );
184
189
// potential custom logic for session id (ex. switching between hosts)
185
190
$ this ->setSessionId ($ sid );
186
191
session_start ();
192
+ if (isset ($ _SESSION ['destroyed ' ])
193
+ && $ _SESSION ['destroyed ' ] < time () - $ this ->sessionConfig ->getCookieLifetime ()
194
+ ) {
195
+ $ this ->destroy (['clear_storage ' => true ]);
196
+ }
197
+
187
198
$ this ->validator ->validate ($ this );
188
199
$ this ->renewCookie ($ sid );
189
200
@@ -498,7 +509,33 @@ public function regenerateId()
498
509
return $ this ;
499
510
}
500
511
501
- $ this ->isSessionExists () ? session_regenerate_id (true ) : session_start ();
512
+ if ($ this ->isSessionExists ()) {
513
+ // Regenerate the session
514
+ session_regenerate_id ();
515
+ $ newSessionId = session_id ();
516
+ $ _SESSION ['new_session_id ' ] = $ newSessionId ;
517
+
518
+ // Set destroy timestamp
519
+ $ _SESSION ['destroyed ' ] = time ();
520
+
521
+ // Write and close current session;
522
+ session_commit ();
523
+
524
+ // Called after destroy()
525
+ $ oldSession = $ _SESSION ;
526
+
527
+ // Start session with new session ID
528
+ session_id ($ newSessionId );
529
+ session_start ();
530
+ $ _SESSION = $ oldSession ;
531
+
532
+ // New session does not need them
533
+ unset($ _SESSION ['destroyed ' ]);
534
+ unset($ _SESSION ['new_session_id ' ]);
535
+ } else {
536
+ session_start ();
537
+ }
538
+
502
539
$ this ->storage ->init (isset ($ _SESSION ) ? $ _SESSION : []);
503
540
504
541
if ($ this ->sessionConfig ->getUseCookies ()) {
0 commit comments