Unexpected loss of PHP Session isn’t something you deal with every day, but when it happens, it can be incredibly frustrating to debug. In this post, I’ll share a personal experience and walk you through the process of identifying and resolving the issue.
🚨 The Issue: CSRF Token Invalid After Multiple Submits
While working on one of my projects, I noticed that the CSRF token was valid during the first and second form submissions, but on the third attempt, it became invalid. After tracing the code, I discovered that PHP session data was mysteriously disappearing.
🔍 The Clue: SameSite Warning in the Browser
Firefox Developer Tools displayed the following warning:
Cookie “PHPSESSID” does not have a proper “SameSite” attribute value. Soon, cookies without the “SameSite” attribute or with an invalid value will be treated as “Lax”. This means that the cookie will no longer be sent in third-party contexts. If your application depends on this cookie being available in such contexts, please add the “SameSite=None“ attribute to it.

This message means that unless you explicitly set the SameSite
attribute for session cookies, browsers may stop sending them in cross-site or even certain same-site contexts, depending on the flow.
✅ Solution: Set Proper Session Cookie Parameters
To ensure that the session cookie behaves correctly, use the following code before calling session_start()
:
session_set_cookie_params([ 'lifetime' => 3600, 'path' => '/', 'domain' => $_SERVER['HTTP_HOST'], 'secure' => true, 'httponly' => true, 'samesite' => 'None'
]);
session_start();
🔸 If your site does not use HTTPS, set secure
to false
and use 'Lax'
instead of 'None'
for the SameSite
value.
💡 Advanced Strategy: Store Session in a Static Variable
If you still experience unexpected session loss, consider storing session data in a static variable inside your Header class. Here’s how you can do it:
First, add a static property named $session
to your header class, and then insert the following code into the constructor:
public function __construct() { session_set_cookie_params([ 'lifetime' => 3600, 'path' => '/', 'domain' => $_SERVER['HTTP_HOST'], 'secure' => true, 'httponly' => true, 'samesite' => 'None' ]); session_start(); self::$session = $_SESSION; session_write_close();
} public static function writeSessionData(string $key, mixed $data) { session_start(); $_SESSION[$key] = $data; self::$session = $_SESSION; session_write_close();
}
After this, you can remove direct calls to session_start()
in other files, and instead use the static method to store session values:
header::writeSessionData('user_id', $user_id);
📌 Conclusion
The root cause was not a bug in the PHP logic, but a misconfiguration in how the session cookie was being handled by the browser. Paying attention to browser DevTools and using secure, modern cookie attributes can save you hours of debugging. If your project grows in complexity, consider abstracting session access for greater control and reliability.