Reputation: 109
A bug exists when using various PHP framework session drivers with PHP 7.0. I initially experienced this issue while using the CodeIgniter database driver and assumed it was a CodeIgniter issue but have since experienced it on multiple sessions drivers and multiple frameworks. At this point I have safely concluded that the type of session driver is irrelevant - seemingly at random, the application will crash and the logs (I've tried both Apache and php-fpm + nginx) fill up with the following:
PHP Fatal error: session_start(): Failed to initialize storage module: user (path: [whatever I have in my php.ini path])
The drivers I am using do not use the values set in php.ini and regardless of whether I set the session.save_handler to files, redis, etc in php.ini and regardless of the path I set (Redis server if redis, fully-writable folder with files enabled) the errors occur. The path here should never be hit unless a native "session_start()" is called in a php file outside of the framework. Also, calling "session_start()" outside of the framework works fine... so clearly PHP can access the path. It's as if at some point, the sessions driver becomes a hybrid of the framework driver and whatever is set in php.ini. The error message always has "user" for the session.save_handler so obviously that's not being pulled from php.ini... but the path is. Why would this be happening? This is one of those issues that is difficult to describe until you have experienced it... and it's difficult to reproduce because everything seems to work fine even for hundreds of sessions (until it suddenly stops working). Restarting Apache does not correct the issue either - there are a number of issues at play here and I end up just rebooting the machine to avoid the downtime. Obviously the PHP 7 machine will be pulled out of the load balancer rotation now... but I was hoping to have things figured out by now.
I have experienced the issue with PHP 7.0 RC5, RC6, & RC8 compiled on my own as well as the latest Ondřej Surý PPA on Ubuntu 15.10 Wily (7.0.0-2+deb.sury.org~wily+1). I have experienced the issue on CodeIgniter & Symfony, and have experienced the issue regardless of the type of driver used in the framework (files, database, redis) or the session.save_handler set in php.ini (which, again, should be irrelevant here but just thought it should be mentioned). I keep trying combinations and throwing things out in the wild and this issue happens every single time (sometimes it takes 12+ hours depending on the traffic to the website).
Thanks for any help you can provide! I'm open to suggestions and willing to try anything at this point.
Upvotes: 8
Views: 74216
Reputation: 74
Upvotes: 1
Reputation: 41
Its working perfect.
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = sys_get_temp_dir();
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
Upvotes: 4
Reputation: 1468
This error is caused because of the undefined session path.
Open application/config/config.php line no. 383.
Replace the below line
$config['sess_save_path'] = NULL;
with
$config['sess_save_path'] = APPPATH . 'cache/session/';
Don't forget to give write permission to cache/session folder.
Upvotes: 1
Reputation: 2131
I decided to migrate my system and do some much-needed updating. I ran into this issue using Codeigniter 3 and php 7.2. After I found the issue I realized how ridiculous it was and wonder how I didn't figure it out sooner. 😏
Anyway here is the solution at least for me.
Obviously make sure memcacheD is installed:
sudo apt-get update
sudo apt-get install php7.2-memcached
If that is good to go then we can proceed to check everything else.
In Codeigniter's config file "/application/config/config.php" there is a section to to specify session options:
$config['sess_driver'] = 'memcached';
$config['sess_cookie_name'] = 'some_session_name';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = NULL;
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
The line that needed to be changed for me was this line:
$config['sess_save_path'] = NULL;
Make sure you set this to a valid path as documented in CI3's manual. The correct setting will look like this:
$config['sess_driver'] = 'memcached';
$config['sess_save_path'] = 'localhost:11211';
Make sure you change "localhost" to reflect your memcached servers location.
For more info see - Codeignier Session Manual
Also have a look here: php memcacheD Sessions support
In case the comment on the page is removed I am posting here:
If you want to use 'memcacheD' extention not 'memcache' (there are two diffrent extentions) for session control, you should pay attention to modify php.ini
Most web resource from google is based on memcache because It's earlier version than memcacheD. They will say as following
session.save_handler = memcache session.save_path = "tcp://localhost:11211"
But it's not valid when it comes to memcacheD
you should modify php.ini like that
session.save_handler = memcached session.save_path = "localhost:11211"
Look, there is no protocol indentifier
For testing I did this to make user that php it's self wasn't having an issue accessing memcacheD:
session_start();
header('Content-Type: text/plain');
session_start();
if(!isset($_SESSION['visit']))
{
echo "This is the first time you're visiting this server\n";
$_SESSION['visit'] = 0;
}
else
echo "Your number of visits: ".$_SESSION['visit'] . "\n";
$_SESSION['visit']++;
echo "Server IP: ".$_SERVER['SERVER_ADDR'] . "\n";
echo "Client IP: ".$_SERVER['REMOTE_ADDR'] . "\n";
print_r($_COOKIE);
$servers = explode(",", ini_get("session.save_path"));
$c = count($servers);
for ($i = 0; $i < $c; ++$i) {
$servers[$i] = explode(":", $servers[$i]);
}
$mem = new memcached();
$mem->addServer('127.0.0.1', '11211', '1');
$mem->set('011', 'Hello There');
print_r($mem->get('011'));
print_r($mem->getAllKeys());
This allowed me to see that memcacheD was working ok.
Also in your php.ini there are some options to look out for. Just search for [session] or session.save_path. CI3 stated it doesn't use this option from the php.ini file, but it's prob worth setting if you plan to use memcacheD outside the framework and for consistency.
This starts around line ~1327 in the php.ini file:
[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
session.save_handler = memcached
; Argument passed to save_handler. In the case of files, this is the path
; where data files are stored. Note: Windows users have to change this
; variable in order to use PHP's session functions.
;
; The path can be defined as:
;
; session.save_path = "N;/path"
;
; where N is an integer. Instead of storing all the session files in
; /path, what this will do is use subdirectories N-levels deep, and
; store the session data in those directories. This is useful if
; your OS has problems with many files in one directory and is
; a more efficient layout for servers that handle many sessions.
;
; NOTE 1: PHP will not create this directory structure automatically.
; You can use the script in the ext/session dir for that purpose.
; NOTE 2: See the section on garbage collection below if you choose to
; use subdirectories for session storage
;
; The file storage module creates files using mode 600 by default.
; You can change that by using
;
; session.save_path = "N;MODE;/path"
;
; where MODE is the octal representation of the mode. Note that this
; does not overwrite the process's umask.
; http://php.net/session.save-path
;session.save_path = "/var/lib/php/sessions"
session.save_path = "locahost:11211"
One other place to check settings is the mecacheD server config file. Depending on the system it's location may vary. For me, it was located under the /etc/ directory.
/etc/memcached.conf
Image for reference to the errors I was getting:
EDIT
If you are using socket i.e. unix:///some/place/memcached.sock to connect to Memcached server it's not documented on exactly how to make this work. You simply do the following in your config:
$config['sess_save_path'] = "/some/place/memcached.sock:11211";
Upvotes: 2
Reputation: 77
Just changed the permissions of /your-Codeigniter-project/system/cache and its contents to 0777 and it worked. It's actually unable to create the session files due to missing permissions. Use the following command sudo chmod 0777 /your-Codeigniter-project/system/cache
sudo chmod 0777 /your-Codeigniter-project/system/cache/*
Note: Replace 'your-Codeigniter-project' above with your project path.
Upvotes: 1
Reputation: 4425
I had to upgrade my code ignitor to the latest version to solve this problem.
Running on:
CentoOS: 7.6.1810
Mysql: 8.0.15
PHP: PHP 7.3.4
I tried a lot of things like moving the session from the database to files and Memcached. Nothing worked. The only thing that fixed it was going from CI 3.0 to 3.1 and boom it just worked like it was supposed to.
Hope it helps someone.
Upvotes: 0
Reputation: 1556
In my case I'm using PHP ver 5.6
with CI ver 3.4
(Codeigniter)
Server: BIGROCK
I found these problems in my live server.
Then after long time. I just tried to delete my Database and re Create it.
Then only I went know that I didn't give permission The User to Access the Database.
So When you have finished Creating your Database and User, You should probably give permissions ( previlleges ) to the user to access the Database.
Let me know if it useful in your case. Thank you.
Upvotes: 1
Reputation: 51
This is usually is due to the session not being able to connect to whichever driver it uses (file, database).
I resolved the issue by looking at the config.php
file
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
So since I used a database it means that it doesn't connect for some reason! (For files probably it doesn't have the permission to write the cached files )
Next I turned on the log
$config['log_threshold'] = 4;
Where 4 = All Messages
.. Then refresh the page, and now I have in application/logs
a file called log-#.php
where #
is a date.
INFO - 2017-08-30 10:05:41 --> Database Driver Class Initialized
ERROR - 2017-08-30 10:05:41 --> Severity: Warning --> mysqli::real_connect(): (HY000/1045): Access denied for user 'user'@'localhost' (using password: YES) /var/system/database/drivers/mysqli/mysqli_driver.php 202
ERROR - 2017-08-30 10:05:41 --> Unable to connect to the database
ERROR - 2017-08-30 10:05:41 --> Severity: Warning --> mysqli::real_connect(): (HY000/1045): Access denied for user 'user'@'localhost' (using password: YES) var/system/database/drivers/mysqli/mysqli_driver.php 202
ERROR - 2017-08-30 10:05:41 --> Severity: Error --> session_start(): Failed to initialize storage module: user (path: ci_sessions) /var/system/libraries/Session/Session.php 140
So I just make sure that the user can access the database and it worked.
Upvotes: 5
Reputation: 1587
This happens only if the session_save_path is not valid, if you are storing your session data in a database then the session table must be created so that CI saves the data else you will end up with this error. Hope helped someone
Upvotes: 0
Reputation: 164
We just ran into a similar issue, where we were setting our own custom handler with session_set_save_handler
to go to memcached, but kept getting this error:
Warning: session_write_close(): Failed to write session data (user). Please verify that the current setting of session.save_path is correct (/var/lib/php/7.0/session) in Unknown on line 0
Turns out that the "write" function needs to return a boolean value (just like start), but it's the only function for session_set_save_handler that doesn't mention any return values in the official PHP docs. So while it looks like it's reverting to the default session handler, it's just giving the error for the default session handler.
The error nor the doc pages would never have led us to a solution...
Upvotes: 0
Reputation: 157
function _open should return true to avoid this error.
It can not be null or empty whatever we use either database or file.
When we use database to store session data, we keep it blank or no Boolean return. that is the main reason for this error.
class session_handler
{
public function __construct()
{
session_set_save_handler(
array($this, "_open"),
array($this, "_close"),
array($this, "_read"),
array($this, "_write"),
array($this, "_destroy"),
array($this, "_gc")
);
}
public function _open($savePath, $sessionId)
{
return true;
}
public function _close() { }
public function _read($id) { }
public function _write($id, $data) { }
public function _destroy($id) { }
public function _gc($max) { }
}
It is only for PHP 7. I do not know it is a bug or not.
Upvotes: 6
Reputation: 14752
This error occurs when the open()
function of the session handler doesn't return boolean TRUE, which obviously means some kind of failure.
It could be failure to connect to a database, failure to open a file, a non-existent directory, etc. - that depends on what the session handler actually uses.
Upvotes: 8
Reputation: 109
I believe I have figured out the issue; I will close out this question. Basically, it appears that when an issue occured with the framework session driver/config (sql connections exceeded, out of memory issue with Redis, etc) it would revert to attempting to use the sess.save_path set in php.ini while still using the framework session driver. So unless the framework driver is compatible with the default sess.save_path in php.ini, this error occurs. To me, it would make more sense to also revert to the sess.save_handler in php.ini as well... but if this is a problem obviously there are bigger issues with the app configuration that need to be resolved.
It's not this error itself breaking sessions... it was an underlying issue with the framework session drivers. I feel dumb... but the logs basically sent me on a wild goose chase. Restarting nginx or Apache would not resolve the issue since the issue was elsewhere. I believe there are still kinks to be worked out with the available PHP 7 Redis libraries and the SQL issues were my fault. After seemingly trying a number of combinations and getting the same result, the issue appeared more cryptic. I still get strange errors using Redis sessions on PHP 7 but, like I said, the PHP 7 Redis library is not very mature.
Upvotes: 0
Reputation: 19
i change on my php.ini:
session.save_path = "N;/path" **to** session.save_path = "/tmp"
and i restart my php7-fpm
Upvotes: 0