使用 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 相关文章推荐
我的论坛源代码(十)
Oct 09 PHP
php 设计模式之 工厂模式
Dec 19 PHP
php数字游戏 计算24算法
Jun 10 PHP
PHP实现抓取Google IP并自动修改hosts文件
Feb 12 PHP
PHP多态代码实例
Jun 26 PHP
php curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
Nov 30 PHP
详解WordPress中过滤链接与过滤SQL语句的方法
Dec 18 PHP
php HTML无刷新提交表单
Apr 05 PHP
解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示
Nov 25 PHP
thinkphp 字母函数详解T/I/N/D/M/A/R/U
Apr 03 PHP
php中类和对象:静态属性、静态方法
Apr 09 PHP
PHP编程实现计算抽奖概率算法完整实例
Aug 09 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串行化与反串行化实例分析
2016/12/27 PHP
PHP封装的非对称加密RSA算法示例
2018/05/28 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
javascript for循环设法提高性能
2010/02/24 Javascript
Js日期选择器并自动加入到输入框中示例代码
2013/08/02 Javascript
JS数组去重与取重的示例代码
2014/01/24 Javascript
extjs每个组件要设置唯一的ID否则会出错
2014/06/15 Javascript
ztree获取当前选中节点子节点id集合的方法
2015/02/12 Javascript
JavaScript动态改变表格单元格内容的方法
2015/03/30 Javascript
JavaScript截断字符串的方法
2015/07/15 Javascript
node.js Sequelize实现单实例字段或批量自增、自减
2016/12/08 Javascript
微信小程序页面调用自定义组件内的事件详解
2019/09/12 Javascript
JS实现联想、自动补齐国家或地区名称的功能
2020/07/07 Javascript
[05:06]DOTA2-DPC中国联赛 正赛 VG vs Magma选手采访
2021/03/11 DOTA
vc6编写python扩展的方法分享
2014/01/17 Python
Python的字典和列表的使用中一些需要注意的地方
2015/04/24 Python
Python文件读取的3种方法及路径转义
2015/06/21 Python
举例讲解Python中字典的合并值相加与异或对比
2016/06/04 Python
Python利用requests模块下载图片实例代码
2019/08/12 Python
python3中利用filter函数输出小于某个数的所有回文数实例
2019/11/24 Python
python将dict中的unicode打印成中文实例
2020/05/11 Python
Selenium环境变量配置(火狐浏览器)及验证实现
2020/12/07 Python
REISS英国官网:伦敦High Street最受欢迎品牌
2016/12/21 全球购物
Burberry英国官网:英国标志性奢侈品牌
2017/03/29 全球购物
德国大型和小型家用电器网上商店:Energeto
2019/05/15 全球购物
Timberland德国官网:靴子、鞋子、衣服、夹克及配件
2019/12/10 全球购物
J2EE面试题
2016/03/14 面试题
员工培训邀请函
2014/01/11 职场文书
五水共治一句话承诺
2014/05/30 职场文书
2015年材料员工作总结
2015/04/30 职场文书
离职信范文
2015/06/23 职场文书
结婚喜宴迎宾词
2015/08/10 职场文书
Python实现智慧校园自动评教全新版
2021/06/18 Python
VUE中的v-if与v-show区别介绍
2022/03/13 Vue.js
详解MongoDB排序时内存大小限制与创建索引的注意事项
2022/05/06 MongoDB