使用 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 相关文章推荐
Zend Guard一些常见问题解答
Sep 11 PHP
PHP+MySQL 手工注入语句大全 推荐
Oct 30 PHP
PHP字符串长度计算 - strlen()函数使用介绍
Oct 15 PHP
php通过递归方式复制目录和子目录的方法
Mar 13 PHP
php读取torrent种子文件内容的方法(测试可用)
May 03 PHP
PHP实现Google plus的好友拖拽分组效果
Oct 21 PHP
关于PHP定时发送服务的解决办法
Apr 23 PHP
PHP简单实现解析xml为数组的方法
May 02 PHP
php微信开发之图片回复功能
Jun 14 PHP
php设计模式之装饰模式应用案例详解
Jun 17 PHP
PHP字符串与数组处理函数用法小结
Jan 07 PHP
记Laravel调用Gin接口调用formData上传文件的实现方法
Dec 12 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下过滤HTML代码的函数
2007/12/10 PHP
php 设计模式之 单例模式
2008/12/19 PHP
php实现分页工具类分享
2014/01/09 PHP
php pdo oracle中文乱码的快速解决方法
2016/05/16 PHP
PHP仿微信多图片预览上传实例代码
2016/09/13 PHP
PHP设置Cookie的HTTPONLY属性方法
2017/02/09 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
PHP实现数组根据某个字段进行水平合并,横向合并案例分析
2019/10/08 PHP
比较详细的关于javascript 解析json的代码
2009/12/16 Javascript
window.name代替cookie的实现代码
2010/11/28 Javascript
jquery中对于批量deferred的处理方法
2014/01/22 Javascript
JavaScript必知必会(六) delete in instanceof
2016/06/08 Javascript
JQuery页面随滚动条动态加载效果的简单实现(推荐)
2017/02/08 Javascript
详解Vue路由开启keep-alive时的注意点
2017/06/20 Javascript
JavaScript变量基本使用方法实例分析
2019/11/15 Javascript
centos下更新Python版本的步骤
2013/02/12 Python
Python设置默认编码为utf8的方法
2016/07/01 Python
Python 实现链表实例代码
2017/04/07 Python
Python数据结构与算法之列表(链表,linked list)简单实现
2017/10/30 Python
用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)
2019/01/08 Python
Python使用itchat模块实现简单的微信控制电脑功能示例
2019/08/26 Python
vue学习笔记之动态组件和v-once指令简单示例
2020/02/29 Python
python2和python3哪个使用率高
2020/06/23 Python
浅析Python中字符串的intern机制
2020/10/03 Python
Python3中对json格式数据的分析处理
2021/01/28 Python
一道写SQL的面试题和答案
2013/11/19 面试题
体育系毕业生求职自荐信
2014/04/16 职场文书
2014幼儿园小班工作总结
2014/11/10 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
支行行长岗位职责
2015/02/15 职场文书
2015年优质护理服务工作总结
2015/04/08 职场文书
小学班主任工作随笔
2015/08/15 职场文书
党校团干班培训心得体会
2016/01/06 职场文书
调研报告的主要写法
2019/04/18 职场文书
springcloud之Feign超时问题的解决
2021/06/24 Java/Android
Python 使用 Frame tkraise() 方法在 Tkinter 应用程序中的Frame之间切换
2022/04/24 Python