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

Sha*_*oni 12 php session codeigniter

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

这里,如果我的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;
Run Code Online (Sandbox Code Playgroud)

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

$this->session->set_userdata('user',$result); //$result works fine, it produces
right result
Run Code Online (Sandbox Code Playgroud)

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

$this->session->userdata['user']['name']; //name here is an element in result array
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

严重性:注意

消息:未定义的索引:用户

文件名: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;
Run Code Online (Sandbox Code Playgroud)

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

数据库截图

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

Don*_*nic 5

你的问题有几个部分,我会轮流回答.

关于从会话中检索值

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

$this->session->userdata['user']['name']; // Bad
Run Code Online (Sandbox Code Playgroud)

正如文档所描述的那样,您应该将要检索的值的键作为参数传递给userdata方法:

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

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

$user = $this->session->user;
// Now you can echo $user['name'];
Run Code Online (Sandbox Code Playgroud)

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

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

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

关于你的 sess_save_path

从你的问题的措辞,我认为你想使用files会话驱动程序,只尝试database驱动程序进行测试.如果这是正确的,那么您应修复的文件会话配置存在问题.

根据文件:

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

评论config/config.php也说:

警告:仅支持绝对路径!

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

$config['sess_save_path'] = 'ci_sessions'; // Bad
Run Code Online (Sandbox Code Playgroud)

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

将路径更改为绝对路径,并确保您的Web服务器可以写入它. 再次来自文档

mkdir /<path to your application directory>/sessions/
chmod 0700 /<path to your application directory>/sessions/
chown www-data /<path to your application directory>/sessions/
Run Code Online (Sandbox Code Playgroud)

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

$config['sess_save_path'] = '/<path to your application directory>/sessions/';
Run Code Online (Sandbox Code Playgroud)

  • 不,我尝试了一切所有建议,但没有任何工作.最后,我发现问题,CI 3.1.6不支持PHP 7.1,当我回到5.6时,它开始保存会话.非常感谢你的帮助. (3认同)

Vic*_*kel 1

如果您阅读Codeigniter 类参考 setuserdata期望第二个参数是一个值,那么在第一个参数是键的情况下,就会出现错误。

使用 Codeigniter 方式,您将无法实现您想要的,因为它使用:

像这样设置:

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

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

这样:

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

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

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

得到:echo $_SESSION['user']['name'];

请参阅php 手册中有关 $_SESSION 的内容

笔记:

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

这是由于您的ENVIRONMENT设置所致,因为您error_reporting在生产(实时)服务器上受到限制。这是在您的 root 中设置的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;
}
Run Code Online (Sandbox Code Playgroud)