会话不在localhost中工作但在实时服务器中工作(Codeigniter)

时间:2017-09-21 09:15:38

标签: php codeigniter session

我从昨天开始就面对这个问题,但我无法解决这个问题。问题是会话在本地环境中不起作用,但出于测试目的,我将相同的文件放在实时服务器上,它们都可以正常工作。

如果我的 config.php 文件:

$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;

以下是我在一个模型文件中保存数据的方法

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

在我看来,我试图通过以下方式访问:

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

我收到此错误:

  

严重性:注意

     

消息:未定义索引:用户

     

文件名:home / home.php

     

行号:2

令我惊讶的是,这个相同的代码在服务器上运行没有任何错误。

,为了能够知道Codeigniter会话保存的数据,我尝试了数据库方法。

我在 config.php 文件

中将代码更改为以下内容
$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;

不插入一行数据,而是插入四行。请参阅下面的数据库截图(最后四行)。

Database Screenshot

有人可以指出错误吗?任何帮助将不胜感激。

7 个答案:

答案 0 :(得分:6)

你的问题有几个部分,我会依次回答。

关于从会话中检索值

userdata()是一种方法。您访问它的方式将其视为一个数组:

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

As the docs describe,您应该将要检索的值的键作为参数传递给userdata方法:

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

更简单的是使用更新的语法:

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

关于数据库中的4个会话记录

检查timestamp字段。它们显示3个不同的时间,这意味着这些是网站上的3个独立事件。第一个发生在1501911275,然后6秒后又有2个记录,然后是139秒后的最后一个记录。这些代表对网站的3个单独请求 - 可能您正在访问不同的页面,或者测试和重新加载。

至于为什么有多条记录,这是因为会话ID会定期重新生成。具体发生的频率取决于您的配置,请参阅sess_time_to_update配置选项。它们被销毁的频率也取决于您的配置(请参阅文档同一部分中的sess_regenerate_destroy) - 但通常较旧的会话记录会暂停一段时间,之后会通过垃圾回收进行清理。因此,虽然您只有1个“当前”会话记录,但旧记录可能会持续一段时间。

关于您的sess_save_path

根据您问题的措辞,我认为您希望使用files会话驱动程序,并且只尝试使用database驱动程序进行测试。如果这是正确的,那么您应该修复文件会话配置中的问题。

According to the docs

  

$ config ['sess_save_path']仅支持绝对路径。

config/config.php中的评论也说:

  

警告:仅支持绝对路径!

您的配置指定会话数据应保存在ci_sessions中,这不是绝对路径:

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

我不确定将如何解释,但我的猜测是该目录不存在,并且Web服务器将无权创建它。我无法想象为什么它可以在您的实时服务器上运行。

将路径更改为绝对路径,并确保您的Web服务器可以写入该路径。 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/

(将www-data更改为您的Web服务器正在运行的用户)。然后:

$config['sess_save_path'] = '/<path to your application directory>/sessions/';

答案 1 :(得分:1)

如果您阅读Codeigniter Class Reference setuserdata,则期望第二个参数为值,如果第一个参数是键,则为错误。

使用Codeigniter方式,您将无法实现您想要的效果:

像这样的

set

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

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

像这样的

get

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

另一方面使用vanilla php $_SESSION你可以像这样实现它:

设置:$_SESSION['user']=$result;

获取:echo $_SESSION['user']['name'];

php manual

查看$ _SESSION

注意:

  

令我惊讶的是,这个相同的代码在服务器上运行没有任何错误。

这是由于您的ENVIRONMENT设置,因为您在生产(实时)服务器上error_reporting受限。这是在根目录index.php中设置的。

define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');更改为:define('ENVIRONMENT', 'production');,您也不会在本地主机上看到错误。

<强>更新

实际上$this->session->set_userdata('name', $name);有效,但函数userdata()只接受一个参数并期望它是一个字符串

如果你查看会话库(/system/libraries/Session/Session.php),你会发现它靠近第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;
}

答案 2 :(得分:0)

请遵循以下

在config.php中

Set $config['sess_save_path'] = NULL;

正如您所说<{1}} 以上$this->session->set_userdata('user',$result); //$result works fine, it produces应该是这样的

$result

如何访问会话密钥

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

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

答案 3 :(得分:0)

似乎问题出在PHP 7.1版本上,因为CI 3.1.6不支持PHP版本。

我不确定这是否是正确的解释但是当我切换回PHP 5.6版本时,一切都开始正常工作。

答案 4 :(得分:0)

我认为访问具​​有错误语法的会话数据存在问题。您可以使用以下语法设置会话数据并获取会话数据。

设置会话数据的示例

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

获取存储的会话数据的示例

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

答案 5 :(得分: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]

答案 6 :(得分:0)

我正在做很多研发工作,但问题没有解决,但是突然我检查了我的MySQL版本,当我更改SQL版本时它就可以工作。如果您有任何此类问题,可以检查您的版本,以便获得结果。