12

I have been facing this issue since yesterday and yet I could not resolve this. Issue is sessions are not working in local environment but when for a testing purpose I put the same files on a live server, they work all okay.

Here if my config.php file:

$config['sess_driver'] = 'files';
$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;

$config['cookie_prefix']    = '';
$config['cookie_domain']    = '';
$config['cookie_path']      = '/';
$config['cookie_secure']    = FALSE;
$config['cookie_httponly']  = FALSE;

Here is how I save the data in one of my model files

$this->session->set_userdata('user',$result); //$result works fine, it produces
right result

In my view, I tried to access this by:

$this->session->userdata['user']['name']; //name here is an element in result array

I get this error:

Severity: Notice

Message: Undefined index: user

Filename: home/home.php

Line Number: 2

To my surprise, this same code runs without any error on server.

Also, to be able to know the data being saved by Codeigniter sessions, I tried database method.

I changed the code to below in config.php file

$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_sessions';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;

Instead of inserting one row of data, it inserts four. Please see below screenshot from the database (last four rows).

Database Screenshot

Can anybody point to the error? Any help will be appreciated.

mega6382
  • 9,211
  • 17
  • 48
  • 69
Guy in the chair
  • 1,045
  • 1
  • 13
  • 42

7 Answers7

5

Your question has a few parts, I'll answer each in turn.

Regarding retrieving values from the session

userdata() is a method. The way you are accessing it treats it as an array:

$this->session->userdata['user']['name']; // Bad

As the docs describe, you should pass the key of the value you want to retrieve as a parameter to the userdata method:

$user = $this->session->userdata('user');
// Now you can echo $user['name'];

Even simpler is to use the newer syntax:

$user = $this->session->user;
// Now you can echo $user['name'];

Regarding the 4 session records in the database

Check the timestamp fields. They show 3 different times, meaning those are 3 separate events on the site. The first occurs at 1501911275, then 6 seconds later there are another 2 records, and then 139 seconds later the last record. Those represent 3 separate requests to the site - probably you were visiting different pages, or testing and reloading.

As to why there are multiple records, that's because the session ID is periodically regenerated. Exactly how often that happens depends on your configuration see the sess_time_to_update config option. How often they are destroyed also depends on your config (see sess_regenerate_destroy in the same section of the docs) - but normally older session records stick around for a while and are cleaned up later by garbage collection. So while you have only 1 "current" session record, old records can persist for a while.

Regarding your sess_save_path

From the wording of your question I think you want to use the files session driver, and only tried the database driver for testing. If that's correct, there is a problem in your files session configuration which you should fix.

According to the docs:

only absolute paths are supported for $config['sess_save_path'].

The comments in config/config.php also say:

WARNING: Only absolute paths are supported!

Your configuration specifies that session data should be saved in ci_sessions, which is not an absolute path:

$config['sess_save_path'] = 'ci_sessions'; // Bad

I am not sure how will be interpreted, but my guess is the directory won't exist, and the web server will not have permissions to create it. I can't imagine why it works on your live server.

Change the path to an absolute path, and make sure your web server can write to it. Again from the docs

mkdir /<path to your application directory>/sessions/
chmod 0700 /<path to your application directory>/sessions/
chown www-data /<path to your application directory>/sessions/

(change www-data to the user your web server is running as). And then:

$config['sess_save_path'] = '/<path to your application directory>/sessions/';
Don't Panic
  • 13,965
  • 5
  • 32
  • 51
  • @shanil Does this help? – Don't Panic Oct 21 '17 at 11:43
  • 3
    No, I tried everything what all suggested but nothing was working. Finally, I found the issue, CI 3.1.6 was not supporting PHP 7.1, when I moved back to 5.6, it started saving the session. Thank you so much for your help. – Guy in the chair Oct 21 '17 at 12:44
  • @ShanilSoni I just set up a Docker container with PHP 7.0 and a fresh install of Codeigniter 3.1.6, and sessions work fine. I don't think it is a PHP version problem. – Don't Panic Oct 21 '17 at 12:58
  • @ShanilSoni If you tried everything suggested here you would have seen that neither of the other 2 answers here actually work, right? – Don't Panic Oct 21 '17 at 13:18
  • That's why I mentioned in my own answer that maybe this is not the correct explanation but that worked somehow. Yes, none of the answers mentioned here did work. This error I have been trying to resolve past 15 days and for the pages that required sessions to be read, I commented out that code to have that worked otherwise. – Guy in the chair Oct 22 '17 at 02:17
  • @ShanilSoni OK ... I meant that the other 2 answers here not only don't solve your problem, but will throw errors, they include bad PHP. That's why I wondered if you really had tried them. If you also tried everything in my answer and it didn't help then I am stumped :-) Good luck in any case. – Don't Panic Oct 22 '17 at 11:00
  • Just f.y.i., The problem I mostly encounter when going from PHP 5 to 7 is when arrays are passed to a method as a variable using `method($arr['param'])` which will break in PHP 7 when something else than an array is expected. You should first define a variable and then pass it to a method. Maybe one of the functions needed here are doing this that way. See the answer on this post: https://stackoverflow.com/questions/35906624/php-notice-array-to-string-conversion-only-on-php-7 You should see a notice in your error log (if enabled) if this is the case. – AltShiftZero Oct 27 '17 at 10:06
  • I got this issue when in my webhosting I select PHP 7.0, then I change to 7.2, after that the sessions works! – Taufik Nur Rahmanda Mar 07 '18 at 02:00
  • @Don'tPanic thanks for the detailed answer, i am facing similar issue and i have noticed that for each page refresh there is a new entry created in ci_sessions table. I recently have started dabbling in php, can you pls suggest how should i debug? I'm working on a code igniter application, using database for persisting sessions. Live site works but when i test changes on my local machine using ngrok it start acting weird... – Rafay Jul 31 '18 at 12:58
1

If you read the Codeigniter Class Reference setuserdata expects the second argument to be a value, that in case first argument is a key, hence the error.

with the Codeigniter way, you won't be able to achieve what you want as it uses:

set like this:

$result=array('name'=>'john doe');

$this->session->set_userdata($result); or $this->session->set_userdata('name','john doe');

get like this:

echo $this->session->userdata(['name']);

on the other hand using vanilla php $_SESSION you can achieve it like so:

set: $_SESSION['user']=$result;

get: echo $_SESSION['user']['name'];

see about $_SESSION at php manual

note:

To my surprise, this same code runs without any error on server.

this is due to your ENVIRONMENT setting, as you have error_reporting limited at the production (live) server. This is set in your root index.php.

change define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development'); to: define('ENVIRONMENT', 'production'); and you won't see the error on your localhost as well.

update:

Actually $this->session->set_userdata('name', $name); works, but the function userdata() only accepts one argument and expects it to be a string

if you look into session library (/system/libraries/Session/Session.php), you'll find it near row 747:

/**
 * Userdata (fetch)
 *
 * Legacy CI_Session compatibility method
 *
 * @param   string  $key    Session data key
 * @return  mixed   Session data value or NULL if not found
 */
public function userdata($key = NULL)
{
    if (isset($key))
    {
        return isset($_SESSION[$key]) ? $_SESSION[$key] : NULL;
    }
    elseif (empty($_SESSION))
    {
        return array();
    }

    $userdata = array();
    $_exclude = array_merge(
        array('__ci_vars'),
        $this->get_flash_keys(),
        $this->get_temp_keys()
    );

    foreach (array_keys($_SESSION) as $key)
    {
        if ( ! in_array($key, $_exclude, TRUE))
        {
            $userdata[$key] = $_SESSION[$key];
        }
    }

    return $userdata;
}
Vickel
  • 7,879
  • 6
  • 35
  • 56
  • No, I already tried this. And set_userdata can have the first parameter as name. I was using it with success. – Guy in the chair Oct 21 '17 at 04:07
  • @ShanilSoni please see my updated answer, if you use php $_SESSION you can resolve your problem. No error on live server is definitely your Environment setting, I've just checked it. – Vickel Oct 21 '17 at 12:02
  • No, I tried everything what all suggested but nothing was working. Finally, I found the issue, CI 3.1.6 was not supporting PHP 7.1, when I moved back to 5.6, it started saving the session. Thank you so much for your help. – Guy in the chair Oct 21 '17 at 12:45
  • I'm clueless then why it was not working in my local environment. I have been facing this issue for 15 days now. When I switched back, it started working somwhow. – Guy in the chair Oct 22 '17 at 02:21
  • did you double check with setting `define('ENVIRONMENT', 'production');` at localhost (like a wrote above). this will suppress the error message. Maybe this is what is confusing you. – Vickel Oct 22 '17 at 07:21
  • @ShanilSoni I've just look into the libraries function userdata(), argument must be a string, so you cannot call it like you do, see the update – Vickel Oct 22 '17 at 18:14
0

Follow these

In config.php

Set $config['sess_save_path'] = NULL;

As you said $this->session->set_userdata('user',$result); //$result works fine, it produces above $result shoulb be like this

$result = array(
    'user'  => 'Ab',
    .....
    'logged_in' => TRUE
);

How To Access session key

echo $this->session->userdata('user');

or

$user = $this->session->userdata('user');
echo $user;
Abdulla Nilam
  • 36,589
  • 17
  • 64
  • 85
  • `sess_save_path` is not supposed to be empty, ever. – Narf Oct 23 '17 at 06:40
  • @Narf check the GitHub repo https://github.com/bcit-ci/CodeIgniter/blob/develop/application/config/config.php#L370-L376 – Abdulla Nilam Oct 23 '17 at 07:17
  • You should check it more carefully yourself: https://github.com/bcit-ci/CodeIgniter/blob/3.1.6/application/config/config.php#L357 – Narf Oct 23 '17 at 07:29
  • It's default config, which not helps unless it changed. And this shows when its important https://github.com/bcit-ci/CodeIgniter/blob/3.1.6/application/config/config.php#L351 – Abdulla Nilam Oct 23 '17 at 07:32
  • I don't even understand what you're trying to say with that. Nothing in there suggests that the value should be left empty. – Narf Oct 23 '17 at 07:41
0

Seems the issue was with PHP version 7.1 as CI 3.1.6 was not supporting that PHP version.

I'm not sure whether this is the correct explanation but when I switched back to PHP version 5.6, everything started working absolutely fine.

Guy in the chair
  • 1,045
  • 1
  • 13
  • 42
  • I just set up a Docker container with PHP 7.0 and a fresh install of Codeigniter 3.1.6, and sessions work fine. I don't think it is a PHP version problem. – Don't Panic Oct 21 '17 at 12:57
  • I have just had the same issue. I have just tested and works fine in PHP 7.0. But there are bugs with session data with PHP 7.1 – user1949366 Oct 22 '17 at 16:21
  • 1
    All 3.1.x versions do support PHP 7.1. Whatever the problem was, it 100% was not that. – Narf Oct 23 '17 at 06:42
0

I think issue with access of session data with incorrect syntax.you can use below syntax for set session data and get session data.

Example for set session data

$session_data = array('name' => "kiran");
$this->session->set_userdata('user', $session_data);

Example for get stored session data

$this->session->userdata('user')['name'];
  • this `$this->session->userdata('user')['name'];`is incorrect! the function userdata is declared as: `public function userdata($key = NULL)`, see session library (/system/libraries/Session/Session.php), you'll find it near row 747: – Vickel Oct 25 '17 at 14:24
0
$config['sess_driver'] = 'files';
$config['sess_cookie_name'] = 'ci_session';
$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;

.htaccess

DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php?/$1 [

L,QSA]

0

I am doing lots of r & d work but problem not solved but suddenly I have check my MySQL version, and when I change my SQL version then it will work. If you have any problem like this you can check your version so that you can get result.

Ram
  • 21
  • 10