What may cause inability to modify session

The objective is to delete id stored in session after logout.


  1. session_start() has been called at the start of the request
  2. Error reporting is turned on

After using the usual unset, if I var_dump, it appears to have truly removed the id, yet the same id is available on subsequent requests to other routes. This doesn’t apply to unset alone, as I have observed when inserting on that request too

		public function signout () {

			unset($_SESSION['login_id'] );
			$_SESSION['jhg'] = 6778; // on next request to another route, this is nowhere to be found, while the login_id remains hail and hearty
			return [];

The only way I was able to successfully clear the value was with this hack

$eds = array_filter($_SESSION, function ($k) {
	return $k != 'login_id';

$_SESSION = []; session_destroy(); 
session_start(); $_SESSION = $eds;

This works because I realized destroying the entire session is persisted across requests. That’s the only operation on the superglobal that works on this particular request/route. Altering the session elsewhere works just as the docs say. What could be going on?

I know it is probably overkill but I just do the following:

/* Logoff Current User */

public function delete($id = NULL) {
    $_SESSION['user'] = NULL;
    return TRUE;

Haha truly an overkill. The reason I objected against using session_destroy is because the session contains keys I imagine might be still be useful during user’s browsing session.

Anyway, I eventually discovered the reason the unset wasn’t working is because of some warning/error getting thrown before the end of the request. You see, at some point, I attempt to store some closure in the session (previous route when validation fails for instance). And it so happens that PHP doesn’t permit (un)serializing closures. So, even though on logout, session was modified, PHP uses some kind of transaction logic at the end of user request to persist modifications to the eventual session.

I equally observed this to be the case for methods between other scripts attempting to read the session after it has been modified. Wonder how intuitive this is for other devs.

So whenever that error occurs, the unset is rolled back. I now use a closure serializer to preserve the closure, and everything works fine.

Thank you for stopping by.

*hale and hearty