CodeIgniter 3(以下简称 CI 3)的 Session 的重大改变就是默认使用了原生的Session,这符合 Session 类库本来的意思,似乎更加合理一些。总体来说,虽然设计理念不同,但为了保证向后兼容性,CI 3 的 Session 类库的使用方法与 CI 2 的差别不是很大。许多在 CI 2 里面关于 Session 的操作方法,在 CI 3 中仍然可用。
CI框架里面,关于 Session 一般的使用过程是这样的:
写数据
1 | // 直接加载默认的files驱动器 |
这跟 CI 2.0 几乎没有区别。接下来看读取 Session 数据的方法:
读数据
1 | // 直接使用PHP原生方式读取session,似乎是官方推荐的方法 |
另外一点需要注意,CI3 开始,如果返回的数据是空,以前为 FALSE
,现在则是 NULL
。
所以,以前的写法:
1 | $name = $this->session->userdata('name'); |
需要换成如下方式:
1 | $name = $this->session->userdata('name'); |
可以使用以下方法判断是否含有某个名称的 session:
1 | // 使用 session 类提供的 has_userdata() 方法 |
删除数据
删除的话则和以前类似:
1 | // 直接 unset 超全局变量 $_SESSION 的key |
总体上看,CI3 的 Session 类库设计理念是更加接近原生的函数和方法,同时为了保持向后兼容性,原来的方法(即:CI2提供的方法)也尽量保留了下来。与此同时,原来的 flash data 理念做了新的设计,加入了 temp data 的概念,那么这两个 data 有什么区别呢?
flash data、temp data 与 user data 的区别
这三种 session 数据的名字是CI约定俗成的,指代的内容是不一样的,并不存在包含关系。不要错误地认为 user data 包含 flash data 或者 temp data。在CI的 api 设计中,分别应用不同场景:
1、flash data
flash data 的主要特征是:保存的数据是一次性数据,在下次请求中用过一次就没了。
本质上讲,flash data 跟普通的 session 数据无异,CI不过是对该类data的名称做出了特殊标记,保证了它们拥有了只能用一次的特征。所以,你可以使用以下方法将普通的 user data 标记为 flash data:
1 | // 先创建一个session |
flash data的适用场景是:将操作结果返回到下一次请求的页面上。比如:有个保存操作,提交后会跳转到一个新的页面,你可以使用 flash data 保存一句话:数据保存成功!该句话只在跳转的页面显示一次,再次刷新跳转页面,就不会显示了。
2、temp data
temp data 的主要特征是:保存的数据在规定的时间内有效,它的生命期由方法 $this->session->set_tempdata('item', 'value', 300)
设置,其中的 300
意思是:该 session 数据的有效期为5分钟,超过规定时间(即便是 session 还没过期)就会失效,它的时效性介于 flash data 和 user data 之间。它和 flash data 在本质上是类似的,也可以从普通的 session 转化过来:
1 | // 先创建一个session |
temp data 的适用场景是:保存一些更加细粒度的、更加隐私的 session 数据。比如某些令牌 token,比较重要,为了安全让它的生命期更短一些,可以保证安全。temp data 的设计从某种方面保证了 session 拥有不同生命期的数据。
3、user data
user data 的主要特征是:保存的数据在 session 有效期内均有效,它的生命期由 sess_expiration
设置,一般默认是7200s,而且它也是生命期最长的。
flash data、temp data 与 user data 的读取
CI Session 类中的 flash data、temp data 与 user data,都能以 $_SESSION['item']
的方式获取到。同时,它们又可以使用各自的方法获取到:
1 | // 使用PHP原生方法:三种类型的数据都能得到 |
但是要注意:这几种数据是分割开来的,不能使用 $this->session->userdata('item')
方法,去访问一个设为 flash data 的数据:
1 | $this->session->set_tempdata('item', 'value', 300); |
Session 数据的删除与销毁
Session 数据的删除可以理解为细粒度的删除某个 session 数据,方法如下:
1 | // 删除名为 item 的 user data |
session 销毁,则会使所有类型的数据失效,包括 flash data 和 temp data:
1 | // PHP原生销毁session的方法,推荐的方式 |
扩展内容:flash、temp 及 user data 的设计思路
首先,三种类型的数据必定存在于 $_SESSION
超全局变量中。也就是说,使用 set_tempdata()
和 set_flashdata()
方法,都会把对应的名称加入到 $_SESSION
超全局变量中。不过这还没完,CI会用一个名为 __ci_vars
的 session 数据来区分 flash、temp 与 user data 的不同。
1 | // CI3:会定义一个名为 __ci_vars 的 session 变量,变量值为一个数组 |
使用 set_flashdata('item', 'value')
时,除了 $_SESSION['item'] = 'value'
以外,同时会有:
1 | // 还是首先会被保存到超级变量中 |
而使用 set_tempdata('item2', 'value', 300)
时,也是类似,不过略有区别:
1 | // 还是首先会被保存到超级变量中 |
当使用这些不同类型的数据时,CI首先看 $_SESSION
数组里面是否含有这个 key,然后会根据 $_SESSION['__ci_vars']
数据包中 key 对应的值来判断该 session 是 flash data 还是 temp data。简单地说,就是看对应的值是不是 int 类型。如果是,就认为是 temp data;如果不是,则认为是 flash data。所以,你可以使用 $_SESSION()
方法获得所有类型的数据,也可以使用 unset
方法,删除掉所有类型的数据。
设置完 flash data 和 temp data 的下次请求时,构造函数都会判断 $_SESSION['__ci_vars']
中的特定数据,如果值为 new
的,则置为 old
;如果值是数字,则跟当前的时间戳比较,小于的话,则会删除该 key 对应的数据。
当再次请求时,flash data 中置为 old
的数据自动被删除,无法再次读取;而 temp data 中的 key 已经过期删除,取值为 NULL
。
本文来自 iFixedBug.com,作者为 Zigzag,感谢他的分享,让我对 CI 3 的 session 有了更深的认识和理解。另外,本文对原文部分文字、标点进行了润色,同时对文章和代码排版进行了优化,以便有更好的阅读体验。原文链接:http://www.ifixedbug.com/posts/how-to-use-codeigniter3-session-2