使用 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的特殊设置
Oct 09 PHP
php array_slice函数的使用以及参数详解
Aug 30 PHP
MayFish PHP的MVC架构的开发框架
Aug 13 PHP
PHP多例模式介绍
Jun 24 PHP
PHP ignore_user_abort函数详细介绍和使用实例
Jul 15 PHP
PHP保存带BOM文件的方法
Feb 12 PHP
解决ThinkPHP下使用上传插件Uploadify浏览器firefox报302错误的方法
Dec 18 PHP
盘点PHP和ASP.NET的10大对比!
Dec 24 PHP
PHP判断数组是否为空的常用方法(五种方法)
Feb 08 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
Aug 23 PHP
PHP 多进程与信号中断实现多任务常驻内存管理实例方法
Oct 04 PHP
php查看一个变量的占用内存的实例代码
Mar 29 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读注册表
2006/10/09 PHP
php file_get_contents函数轻松采集html数据
2010/04/22 PHP
javascript removeChild 使用注意事项
2009/04/11 Javascript
表单元素事件 (Form Element Events)
2009/07/17 Javascript
JavaScript 精粹读书笔记(1,2)
2010/02/07 Javascript
腾讯的ip接口 方便获取当前用户的ip地理位置
2010/11/25 Javascript
JS随即打乱数组实现代码
2012/12/03 Javascript
jQuery图片滚动图片的效果(另类实现)
2013/06/02 Javascript
js导入导出excel(实例代码)
2013/11/25 Javascript
jquery获取一个元素下面相同子元素的个数代码
2014/07/31 Javascript
Node.js中使用Log.io在浏览器中实时监控日志(等同tail -f命令)
2014/09/17 Javascript
DOM操作一些常用的属性汇总
2015/03/13 Javascript
javascript中关于&& 和 || 表达式的小技巧分享
2015/04/10 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
2016/12/31 Javascript
AngularJs定时器$interval 和 $timeout详解
2017/05/25 Javascript
angularJS利用ng-repeat遍历二维数组的实例代码
2017/06/03 Javascript
React Native预设占位placeholder的使用
2017/09/28 Javascript
详解IWinter 一个路由转控制器的 Nodejs 库
2017/11/15 NodeJs
JS document form表单元素操作完整示例
2020/01/13 Javascript
原生js+canvas实现贪吃蛇效果
2020/08/02 Javascript
Python的面向对象思想分析
2015/01/14 Python
Python GUI布局尺寸适配方法
2018/10/11 Python
用Python实现筛选文件脚本的方法
2018/10/27 Python
python异步实现定时任务和周期任务的方法
2019/06/29 Python
关于Numpy中的行向量和列向量详解
2019/11/30 Python
pycharm如何实现跨目录调用文件
2020/02/28 Python
使用Keras建立模型并训练等一系列操作方式
2020/07/02 Python
基于Python和C++实现删除链表的节点
2020/07/06 Python
实例教程 纯CSS3打造非常炫的加载动画效果
2014/11/05 HTML / CSS
html5 canvas 简单画板实现代码
2012/01/05 HTML / CSS
中国跨镜手机配件批发在线商店:TVC-Mall
2019/08/20 全球购物
Yahoo-PHP面试题4
2012/05/05 面试题
个人学习党的群众路线教育实践活动心得体会
2014/11/05 职场文书
小学生表扬稿范文
2015/05/05 职场文书
学校学习型党组织建设心得体会
2019/06/21 职场文书
Mybatis-plus在项目中的简单应用
2021/07/01 Java/Android