PHP: Why might session_start fail, claiming "no such file or directory"?
Here's a little problem that bit me after an OS upgrade to a webserver. Whenever session_start was called, PHP would throw a warning message and not actually start the session:
Warning: session_start() [function.session-start]: open(/tmp/php_sessions/sess_5q2snk41jrvq9tt1q8eddprlulm7jaflk0hgtfivm8uhqr2i85u0, O_RDWR) failed: No such file or directory (2) in /srv/www/htdocs/index.php on line 2 Warning: Unknown: open(/tmp/sess_5q2snk41jrvq9tt1q8eddprlulm7jaflk0hgtfivm8uhqr2i85u0, 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 (/tmp/php_sessions) in Unknown on line 0
While this normally means that the directory specified as PHP's session.save_path either does not exist or does not have the appropriate permissions set, I could see quite clearly that that directory in fact did exist and was owned by the appropriate user, with the correct permissions. It took me hours to find out what was wrong. It turns out that the OS upgrade made systemd redirect Apache's (and thus PHP's) references to /tmp to another location, something like /tmp/systemd-private-RiMSxa.
Solution #1: Create the directory
There's multiple solutions to this. One would be to simply create the appropriate directory as needed, as simple as:
mkdir (ini_get ('session.save_path', 0777, true));
Solution #2: Move your sessions elsewhere
A second solution is to simply change your php.ini file, making the session.save_path directive point somewhere outside the /tmp directory, such as /var/lib/php.
Solution #3: Disable private temporary directory
And another would be to disable the redirection (which is what I did, as this is a development server where I sometimes find it useful to inspect the session files manually. For this, find the appropriate configuration file for systemd. For me, this was /usr/lib/systemd/system/apache2.service (the file could also be called httpd.service). In that, find the line:
and change true to false. Save the file, call systemctl daemon-reload and restart Apache.