使用 MySQL 开始 PHP 会话


Posted in PHP onDecember 21, 2006

默认情况下,PHP会话(session)是通过文件来保存的。这样做有以下几个缺点:

    会话文件一般都很小,但文件数却很多,在文件系统中保存许多这样的小文件非常浪费空间,且效率不高。
    分布式的站点难以利用会话文件来共享会话。
    会话文件方式不利于统计在线用户的会话信息。
    为解决以上问题,我们可以考虑用数据库来保存会话信息。

    对于 PHP 开发来说,保存会话用 MySQL 是一个非常不错的选择。MySQL 提供一种建立在内存中的表类型 Heap,如果每条会话数据量很小的话,可以考虑用这种类型的表来进一步优化性能。但是 Heap 类型的表有许多限制,例如它不支持 text 类型的字段,因此如果在无法预测会话数据记录长度的情况下,选择 MyISAM 是比较合适的,这种类型的表没有事物处理开销,对于基于磁盘的表可以得到最优性能。

    下面是 sessions 表的结构:

    DROP TABLE IF EXISTS `sessions`;
    CREATE TABLE `sessions` (
      `session_id` varchar(32) NOT NULL default '',
      `user_id` int(10) unsigned NOT NULL default '0',
      `data_value` text NOT NULL,
      `last_visit` timestamp(14) NOT NULL,
      PRIMARY KEY (`session_id`),
      KEY `user_id` (`user_id`)
    ) TYPE=MyISAM;
    PHP 支持用户会话模块,可以通过 session_set_save_handler 来设置自定义的会话处理函数。因为默认的处理模块是 files,因此要在用 session_set_save_handler 设置会话处理函数之前,先用 session_module_name('user') 来告诉 PHP 使用用户会话模块, 而session_set_save_handler 必须要在 session_start 之前执行。

    用户会话数据在会话处理函数中都是序列化之后的,要取出其中的某个会话变量,可以对其进行反序列化,默认是 php 序列化方式,可以用 session::unserialize 函数来反序列化。

    下面的代码定义了一个用 MySQL 来处理 PHP 会话的类,其中所使用的 class_mysql.php 请参见 《超级简单但超级实用的 PHP 的 mysql 类》 。

    〈?php
    /**
    * @author 马秉尧
    * @copyright (C) 2005 CoolCode.CN
    */

    require_once(“class_mysql.php“);

    class session {
        var $db;
        function session(&$db) {
            $this-〉db = &$db;
            session_module_name('user');
            session_set_save_handler(
                array(&$this, 'open'),
                array(&$this, 'close'),
                array(&$this, 'read'),
                array(&$this, 'write'),
                array(&$this, 'destroy'),
                array(&$this, 'gc')
            );
            session_start();
        }
        function unserialize($data_value) {
            $vars = preg_split(
                '/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\|/',
                $data_value, -1, PREG_SPLIT_NO_EMPTY |
                PREG_SPLIT_DELIM_CAPTURE
            );
            for ($i = 0; $vars[$i]; $i++) {
                $result[$vars[$i++]] = unserialize($vars[$i]);
            }
            return $result;
        }
        function open($path, $name) {
            return true;
        }
        function close() {
            return true;
        }
        function read($session_id) {
            $session_id = $this-〉db-〉escape_string($session_id);
            if ($row = $this-〉db-〉query(“select * from `sessions` where `session_id` = '$session_id' limit 1“)) {
                return $row['data_value'];
            }
            else {
                $this-〉db-〉query(“insert into `sessions` set `session_id` = '$session_id'“);
                return ““;
            }
        }
        function write($session_id, $data_value) {
            $data = $this-〉unserialize($data_value);
            $session_id = $this-〉db-〉escape_string($session_id);
            $data_value = $this-〉db-〉escape_string($data_value);
            $this-〉db-〉query(“update `sessions` set “
                                    . “`user_id` = '{$data['user_id']}', “
                                    . “`data_value` = '$data_value', “
                                    . “`last_visit` = null “
                                    . “where `session_id` = '$session_id'“);
            return true;
        }
        function destroy($session_id) {
            $session_id = $this-〉db-〉escape_string($session_id);
            $this-〉db-〉query(“delete from `sessions` where `session_id` = '$session_id'“);
            return true;
        }
        function gc($lifetime) {
            $this-〉db-〉query(“delete from `sessions` where unix_timestamp(now()) - unix_timestamp(`last_visit`) 〉 $lifetime“);
            return true;
        }
        // get sessions by user_id
        function get($user_id) {
            $user_id = $this-〉db-〉escape_string($user_id);
            return $this-〉db-〉query(“select * from `sessions` where `user_id` = '$user_id'“);
        }
        // get sessions list
        function lists($page, $rows) {
            if ($page == 0) {
                return $this-〉db-〉query(“select * from `sessions` order by `user_id`“);
            }
            else {
                $start = ($page - 1) * $rows;
                return $this-〉db-〉query(“select * from `sessions` order by `user_id` limit $start, $rows“);
            }
        }
    }
    ?〉

    这个类的使用很简单,在原来使用 session_start 的地方,替换成 $session = new session($db) 就可以了。$db 表示 sessions 表所在的数据库。

    另外可以用 get 方法来获取某个用户的所有会话信息,通过 lists 方法来得到所有用户会话列表。这样就可以方便的管理用户会话了。 

PHP 相关文章推荐
PHP静态类
Nov 25 PHP
php正则表达匹配中文问题分析小结
Mar 25 PHP
PHP异常Parse error: syntax error, unexpected T_VAR错误解决方法
May 06 PHP
PHP ignore_user_abort函数详细介绍和使用实例
Jul 15 PHP
php中mkdir函数用法实例分析
Nov 15 PHP
smarty模板引擎从配置文件中获取数据的方法
Jan 22 PHP
php关联数组快速排序的方法
Apr 17 PHP
PHP图像裁剪缩略裁切类源码及使用方法
Jan 07 PHP
Joomla框架实现字符串截取的方法示例
Jul 18 PHP
使用PHP访问RabbitMQ消息队列的方法示例
Jun 06 PHP
在TP5数据库中四个字段实现无限分类的示例
Oct 18 PHP
php使用redis的几种常见操作方式和用法示例
Feb 20 PHP
PHP 编程请选择正确的文本编辑软件
Dec 21 #PHP
PHP 模板高级篇总结
Dec 21 #PHP
PHP函数utf8转gb2312编码
Dec 21 #PHP
小偷PHP+Html+缓存
Dec 20 #PHP
PR值查询 | PageRank 查询
Dec 20 #PHP
转PHP手册及PHP编程标准
Dec 17 #PHP
IIS环境下快速安装、配置和调试PHP5.2.0
Dec 17 #PHP
You might like
php fckeditor 调用的函数
2009/06/21 PHP
解析PHPExcel使用的常用说明以及把PHPExcel整合进CI框架的介绍
2013/06/24 PHP
浅谈php自定义错误日志
2015/02/13 PHP
PHP递归实现汉诺塔问题的方法示例
2017/11/25 PHP
javascript 多级checkbox选择效果
2009/08/20 Javascript
JS 判断undefined的实现代码
2009/11/26 Javascript
jQuery 学习入门篇附实例代码
2010/03/16 Javascript
Javascript中获取出错代码所在文件及行数的代码
2010/09/23 Javascript
myEvent.js javascript跨浏览器事件框架
2011/10/24 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
2015/05/14 Javascript
简单实现限制uploadify上传个数
2015/11/16 Javascript
Javascript数组Array基础介绍
2016/03/13 Javascript
AngularJS 中的指令实践开发指南(一)
2016/03/20 Javascript
使用mock.js随机数据和使用express输出json接口的实现方法
2018/01/07 Javascript
node使用mysql获取数据库数据中文乱码问题的解决
2019/12/02 Javascript
[01:30]DOTA2上海特锦赛现场采访 Loda倾情献唱
2016/03/25 DOTA
python实现的解析crontab配置文件代码
2014/06/30 Python
Python字符串、元组、列表、字典互相转换的方法
2016/01/23 Python
Python实现针对中文排序的方法
2017/05/09 Python
python基础while循环及if判断的实例讲解
2017/08/25 Python
python的文件操作方法汇总
2017/11/10 Python
Python实现的桶排序算法示例
2017/11/29 Python
Python使用pip安装pySerial串口通讯模块
2018/04/20 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
Python截图并保存的具体实例
2021/01/14 Python
Python 里最强的地图绘制神器
2021/03/01 Python
Smallable英国家庭概念店:设计师童装及家居装饰
2017/07/05 全球购物
名人珠宝设计师:Melinda Maria Jewelry
2019/03/06 全球购物
Chemist Warehouse中文网:澳洲连锁大药房
2021/02/05 全球购物
团队口号大全
2014/06/06 职场文书
机电一体化毕业生自荐信
2014/06/19 职场文书
项目负责人岗位职责
2015/02/15 职场文书
2015年教师学期工作总结
2015/04/30 职场文书
慰问信(范文3篇)
2019/10/23 职场文书
Python selenium模拟网页点击爬虫交管12123违章数据
2021/05/26 Python
vue 自定义组件添加原生事件
2022/04/21 Vue.js