3.3 在数据库中存储Session信息
大部分使用PHP的人一旦应用到Session都会使用Cookie。Cookie虽好可是它也会给我们带来一些隐患。
隐患一:
如果客户端机器的Cookie一旦因病毒而失效了,那么Session信息也就相当于没有了。
隐患二:
Session在PHP中默认的是以文件的形式保存在一个临时文件夹里面的,对于一个小型系统来说,这样做完全可以,可是对于一个大型而又被经常访问的系统来说,就不是很好的办法了。假设这个网站一天有1 000个人访问。一个月以后Session的临时文件夹就会有30 000个临时文件。想象一下计算机要从30 000里面找一条session_sid是要花费不少时间的。因此为了提高效率,使用用数据库来保存Session不失为解决这个矛盾的好方法。本节将做这方面的尝试。
本例要点
上面已经提到了,Session在php中默认的是以文件的形式保存在一个临时文件夹里面的。可以通过修改php.ini文件的session.save_handler设置来改变Session的保存方式。默认为session.save_handler =files,必须将其修改为session.save_handler =user,即变为用户自定义方式。
完成这一步后,我们可以创建自己的用户级的Session的保存函数(打开、关闭、写入等),然后必须使用session_set_save_handler函数注册自己创建的Session的保存函数。使用session_set_save_handler函数前,必须先要配置php.ini文件,即session.save_hadler=user,否则,session_set_save_handler函数不会生效。
你如果想让这样的Session跨页面使用,还要在每一个用到Session的脚本文件中加入你自定的函数及用session_set_save_handler函数进行注册,所以,最好的方法是做成一个单独的文件,在每一个要用到Session的脚本中用include来包含进来。
目录结构
数据库的表结构
表3-4 保存Session(db_session)
本例代码
本节使用mysql扩展库来进行数据库操作,2行至5行定义数据库连接用的全局变量,分别为数据名、数据库用户名、密码、主机名(IP地址也可)。
变量为$SESS_DBH数据库连接对象,将在sess_open函数中初始化。
调用get_cfg_var函数取得session的最大有效期。
定义sess_open函数,带两个参数保存路径$save_path(文件保存方法时会用到),Session名称$session_name。这两个参数尽管没有在函数内使用,但必须以这种方式定义sess_open函数。所有Session处理函数都必须遵循此处所示的固定的定义方式。
global的作用是定义全局变量,但是这个全局变量不是应用于整个网站,而是应用于当前页面。
建立数据库连接,并初始化数据库连接对象$SESS_DBH。mysql扩展库中有两种建立数据库连接的函数,mysql_pconnect用于建立与数据库的持久连接,而函数mysql_connect用于建立非持久连接。出现连接错误时,显示错误信息。
指定对象数据库,相当于执行“use数据库名;”的命令。
定义关闭session方法。
读取session函数,参数为session关键字名(随机产生的乱码)。
以session关键字为条件,从表db_session检索出在有效期限内的session信息。
mysql_query函数执行一条MySQL查询。第二个参数为数据库连接,省略时使用上一个打开的连接。
mysql_fetch_row从结果集中以数字数组的形式取得一行。依次调用mysql_fetch_row()将返回结果集中的下一行,如果没有更多行则返回FALSE。成功时,此行的执行结果是将取出来的值放在变量$value中。
向数据库中保存Session信息。
Session的期限是当前时间加上最大有效期后的时间。
插入失败,意味着数据库中已有Session记录,则对Session进行更新处理。
定义删除Session信息的sess_destroy函数,关闭画面时会执行。
定义自动删除过期的Session信息的函数sess_gc。
不带参数的session_module_name函数用于获取目前Session的模块。
注册自定义session函数,包括打开、关闭、写入等。
包含进行自定义Session处理文件。在所有使用自定义Session处理(本节即数据库保存方式)的页面中都必须包含此文件。
调用session_start函数,session处理开始。
设置session变量。
显示session变量。
补充
使用mysql/mysqli扩展库进行数据库操作
本节我们看到了另一种不同PDO的数据库操作方法,即使用mysql/mysqli扩展库进行数据库操作。
为了能够顺利地使用mysql/mysqli扩展库的函数,在Linux环境下必须在编译PHP时添加对MySQL的支持。编译时,只要使用--with-mysql[=DIR]配置选项即可,其中可选的[DIR]指向MySQL的安装目录。虽然本MySQL扩展库兼容MySQL 4.1.0及其以后版本,但是它不支持这些版本提供的额外功能。因此要使用更多的功能,请使用MySQLi扩展库。如果要同时安装mysql扩展库和mysqli扩展库,必须使用同一个客户端库以避免任何冲突。
在Windows环境下也默认未启用它们,因此必须在php.ini中激活php_mysql.dll动态连接库。此外,PHP还需要访问MySQL客户端连接库。PHP的Windows发行版包括了一个libmysql.dll,为了让PHP能和MySQL对话,此文件必须放在Windows的系统路径PATH中。要激活任何PHP扩展库(例如php_mysql.dll),PHP指令extension_dir要被设为PHP扩展库所在的目录。PHP 5下extension_dir取值的一个例子是c:\php\ext。
mysql扩展库提供了丰富的操作MySQL数据库的函数,代码非常简洁。主要的也是经常使用的函数其实都已经在本节的代码中出现了。如mysql_pconnect/mysql_connect函数用于建立与数据库的连接,mysql_query函数用于对MySQL数据的查询,mysql_fetch_row函数用于取得返回结果集合,详细可以参照mysql扩展库的使用手册。