使用 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 pathinfo()获得文件的路径、名称等信息说明
Sep 13 PHP
php面向对象 字段的声明与使用
Jun 14 PHP
linux命令之调试工具strace的深入分析
Jun 03 PHP
php number_format() 函数通过千位分组来格式化数字的实现代码
Aug 06 PHP
PHP递归删除目录几个代码实例
Apr 21 PHP
php连接与操作PostgreSQL数据库的方法
Dec 25 PHP
Yii中实现处理前后台登录的新方法
Dec 28 PHP
PHP实现简单ajax Loading加载功能示例
Dec 28 PHP
浅谈PHP的排列组合(如输入a,b,c 输出他们的全部组合)
Mar 14 PHP
实例分析PHP中PHPMailer发邮件
Dec 13 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
Feb 21 PHP
详解PHP中curl_multi并发的实现
Jun 08 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的超级变量$_GET获取HTML表单(Form) 数据
2011/05/07 PHP
laravel通过a标签从视图向控制器实现传值
2019/10/15 PHP
常用js脚本
2006/12/03 Javascript
javascript的函数、创建对象、封装、属性和方法、继承
2011/03/10 Javascript
Javascript变量函数浅析
2011/09/02 Javascript
JS 操作Array数组的方法及属性实例解析
2014/01/08 Javascript
angular简介和其特点介绍
2015/01/29 Javascript
js实现双击图片放大单击缩小的方法
2015/02/17 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记6)
2015/12/20 Javascript
Angularjs2不同组件间的通信实例代码
2017/05/06 Javascript
angular6根据environments配置文件更改开发所需要的环境的方法
2019/03/06 Javascript
详解vue 自定义marquee无缝滚动组件
2019/04/09 Javascript
js实现时间日期校验
2020/05/26 Javascript
vue循环中点击选中再点击取消(单选)的实现
2020/09/10 Javascript
python操作mysql中文显示乱码的解决方法
2014/10/11 Python
python实现ping的方法
2015/07/06 Python
Python实用工具FuckIt.py介绍
2019/07/02 Python
Python编译为二进制so可执行文件实例
2019/12/23 Python
pytorch实现用CNN和LSTM对文本进行分类方式
2020/01/08 Python
使用OpenCV获取图片连通域数量,并用不同颜色标记函
2020/06/04 Python
Python Dict找出value大于某值或key大于某值的所有项方式
2020/06/05 Python
python 爬虫之selenium可视化爬虫的实现
2020/12/04 Python
Python如何实现感知器的逻辑电路
2020/12/25 Python
Django与AJAX实现网页动态数据显示的示例代码
2021/02/24 Python
华丽的手绘陶瓷:MacKenzie-Childs
2017/02/04 全球购物
加拿大最大的体育用品、鞋类和服装零售商:Sport Chek
2018/11/29 全球购物
外贸实习生自荐信范文
2013/11/24 职场文书
大学生活自我评价
2014/04/09 职场文书
小小商店教学反思
2014/04/27 职场文书
2014年销售部工作总结
2014/12/01 职场文书
司机岗位职责
2015/02/04 职场文书
2015年国际护士节演讲稿
2015/03/18 职场文书
2015学校师德师风工作总结
2015/04/22 职场文书
教师个人师德工作总结2015
2015/05/12 职场文书
2015年青年志愿者工作总结
2015/05/20 职场文书
银行大堂经理培训心得体会
2016/01/09 职场文书