Fix: PHP sessions not saving.

The other day, I was told that the login form for a website I had built had stopped working. I found this very strange, as the site had been working for eight years without any issues. This inspired me to write up a quick guide on the common problems that could prevent PHP from saving session data.

The function session_start is not being called properly.

This is the most common cause of session data not saving. It is also the easiest to fix. Basically, PHP’s session_start function MUST be called before any session data is saved or any output is sent to the browser. The role of this function is to start a new session or resume an existing one (if it exists). Most developers play it safe by placing the session_start function at the top of all of their scripts. Further reading: Check if a PHP session has started.

The session save path is incorrect.

In my case – session data was being lost because the host had failed to specify a correct session save path in their php.ini file.

After some debugging, I quickly came to the conclusion that session variables were not being saved on the server, even though session_start was being used correctly. This meant that the user was being redirected back to the login form, even if their email and password combination was correct.

Unfortunately, the host had configured their server to hide PHP warnings. This hid the cause of the problem. It was only when I added the following piece of code that the issue became clear:

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

As soon as I forced all PHP errors and warnings to display, the following messages began to appear:

Warning: Unknown: open(C:Program Files (x86)PHPTEMPv5.6SessionDatasess_ic0c1dms6tucu69pgailrok1i6, O_RDWR) failed: No such file or directory (2) in Unknown on line 0

Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (C:Program Files (x86)PHPTEMPv5.6SessionData) in Unknown on line 0

Basically, the directory that was supposed to be storing session data did not exist.

Varnish HTTP Cache is deleting HTTP cookies.

On another occasion, I didn’t realise that the production server I was deploying to had Varnish HTTP Cache installed. While I was in the process of debugging the issue, I discovered that a cookie with the PHPSESSID variable did not exist. i.e. There was no HTTP cookie for the site, which meant that PHP could not keep track of user sessions.

In this case, Varnish HTTP Cache was disregarding all HTTP cookies unless the URL matched a certain domain or a certain directory pattern. The configuration file that controlled this behavior was located at:

/etc/varnish/default.vcl

An example:

if (!(req.http.host ~ "(www)?(thisinterestsme).com")) {
    unset req.http.cookie;
}

In the example above, Varnish is unsetting all HTTP cookies unless the host is this particular website. If I setup a new domain called test.com on this server, Varnish will remove all HTTP cookies for it unless I add it to the IF statement above.