业内常说“不理解会话(Session)的概念就等于不懂得PHP网络编程”。当然,这里讲的是PHP语言用于互联网编程的时候。因为HTTP协议是无状态的,所以每次请求结束后,变量和资源就被回收了,那么我们如何保存一些“持久”的信息呢?比如在用户登录之后,系统需要把用户登录的信息保存下来,在整个应用或者站点里面使用。也许你会想到使用数据库来保存,当然这确实是一种解决方案,但是这些数据大部分属于临时数据,用户退出登录之后就没有用了,如果使用数据库不仅浪费资源,而且还需要定期清理,相当麻烦。为了解决这个问题,PHP专门为我们提供了会话模块,来保存这些临时的用户数据。
和大部分的语言环境一样,PHP的Session机制不是非常复杂,客户端只需要保存一个会话ID,即Session ID,每次会话请求都会把这个Session ID传给服务端,并获取服务端接口处理完的数据,整个过程如图3-7所示。
PHP默认的会话存储方式是文件存储,数据会被保存到服务器本地的session.save_path参数设定的目录中(此参数位于php.ini配置文件)。使用的时候,首先需要调用session_start方法开启一个新的Session,然后直接使用PHP预定义变量$_SESSION来进行读取和存储操作,在请求结束时系统会把修改过的会话值保存到存储器中。示例用法如代码清单3-11所示。
小贴士:php.ini是PHP的环境配置文件,在Linux系统下一般会被放在/etc/php.ini目录下。该文件几乎包含了PHP运行环境所需的所有配置,也是我们必须学习的内容之一,由于篇幅原因,本书不做详细讲解。具体配置参数可直接参考官方文档,地址如下http://cn.php.net/manual/zh/ini.list.php。
代码清单 3-11
前面的会话实例实现了一个简单的计数器,逻辑很简单,大家参照着注释就可以很快读懂。这里需要注意的是,Session机制仅适用于有服务器的网络环境中,在以命令行(CLI)脚本运行的情况下是不起作用的。另外,我们可以看到该计数器程序的有效代码只有4行,这也从一个侧面反映了PHP语言的简单高效。
当然我们这里讨论的仅仅是比较简单的Session使用场景,对于相对比较大型一点的网络应用来说,Session的使用就不是这么简单了。比如我们要在多台应用服务器之间共享Session,那就不能把Session信息存放在本地了,这时候我们可能需要把Session集中存储在某个公用的中间件里,比如数据库或者缓存服务器等。好在PHP给我们提供了Session回调接口来帮助我们控制Session的存储方式,实例代码请参考代码清单3-12。
代码清单 3-12
savePath = $savePath;
$this->sessionName = $sessionName;
return true;
}
public function close() {
// 关闭 Session 逻辑
return true;
}
public function read($id) {
// 读取 Session 逻辑
}
public function write($id, $data) {
// 存储 Session 逻辑
}
public function destroy($id) {
// 销毁 Session 逻辑
}
public function gc($maxlifetime) {
// 回收 Session 逻辑
}
}
// 使用 Session 类
new SessionHandler();
上述实例中,我们使用session_set_save_handler方法重写了PHP的Session机制,通过这种方式我们可以很方便地控制Session的存取逻辑来满足我们的需求;此外,这也是我们优化Session机制时必须使用的知识,这些进阶知识我们会在9.1.2节中给大家做进一步的介绍。