PHP实现多服务器session共享之mysql共享

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介:
基于mysql的实现方式代码如下:
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
//===========================================
// 程序:   mysql-Based Session Class
// 功能:   基于mysql存储的 Session 功能类
// 作者:    yejr
// 网站:    http://imysql.cn
// 时间:    2007-01-05
//===========================================
/**
 * 类名:    MySQL Session Class
 * 功能:    自主实现基于MySQL HEAP表存储的 Session 功能
 * 描述:    这个类就是实现Session的功能,基本上是通过设置客户端的Cookie来保存SessionID,
 *          然后把用户的数据保存在服务器端,最后通过Cookie中的Session Id来确定一个数据是否是用户的,
 *          然后进行相应的数据操作
 *
 * 注意: 本类调用了PEAR::DB类,如果有自己的DB类,则可以稍微修改一下代码
 *
 * 备注:数据表初始化SQL语句:
 * CREATE TABLE `sessions` (
 * `sid` varchar(32) NOT NULL default '',
 * `session` longtext,
 * `flush_dt` int unsigned NOT NULL default '0',
 * PRIMARY KEY  (`sid`),
 * KEY `last` (`flush_dt`)
 * ) ENGINE=HEAP;
 */
//设定 SESSION 有效时间,单位是 秒
define('SESS_LIFTTIME', 3600);
define('DB_DSN', 'mysql://root:@localhost/test');
define('DB_NAME','test');
require_once('DB.php');
$gDb    = new DB;
$gDb    = DB::connect(DB_DSN, TRUE);
if (PEAR::isError($gDb))
{
    die($gDb->getMessage());
}
if (!defined('MySQLSession'))
{
    define('MySQLSession',    TRUE);
class Usess
{
    static  $mSessSavePath;
    static  $mSessName;
    static  $mSessMaxTime;
    static  $mTblSess   = 'sessions';
    static  $mTblSessMap;
    static  $mDb;
    // {{{ 初始化构造函数
    /**
     * 构造函数
     *
     * @param string $login_user    登录用户
     * @param int $login_type       用户类型
     * @param string $login_sess    登录Session值
     * @return Esession
     */
    public function __construct()
    {
        self::$mSessMaxTime = SESS_LIFTTIME;
        self::$mTblSessMap  = array(
                'sid'   => 'sid',
                'data'  => 'session',
                'last'  => 'flush_dt',
                );
    }
    // }}}
    /** {{{ sessOpen($pSavePath, $name)
     *
     * @param   String  $pSavePath
     * @param   String  $pSessName
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessOpen($pSavePath = '', $pSessName = '')
    {
        global $gDb;
        self::$mDb  = $gDb;
        self::$mSessSavePath    = $pSavePath;
        self::$mSessName        = $pSessName;
        self::sessGc();
        return TRUE;
    }
    // }}}
    /** {{{ sessClose()
     *
     * @param   NULL
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessClose()
    {
        return TRUE;
    }
    // }}}
    /** {{{ sessRead($wSid)
     *
     * @param   String  $wSid
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessRead($wSid = '')
    {
        global $db;
        $wSql    = sprintf("SELECT * FROM `%s`.`%s` WHERE `%s` = '%s';",
                        DB_NAME,
                        self::$mTblSess,
                        self::$mTblSessMap['sid'],
                        $wSid
                );
        //这里一定要用 DB_FETCHMODE_ASSOC,否则取回的数组只能用数字做下标
        if (!PEAR::isError($row = self::$mDb->getRow($wSql, null, DB_FETCHMODE_ASSOC)))
        {
            //session已经存在了
            if (is_array($row) && 1 <= count($row))
            {
                return $row[self::$mTblSessMap['data']];
            }
            else
            {
                $wSql    = sprintf("INSERT INTO `%s`.`%s` VALUES ('%s', '', UNIX_TIMESTAMP(NOW()));",
                                DB_NAME,
                                self::$mTblSess,
                                $wSid
                        );
                if (!PEAR::isError(self::$mDb->query($wSql)))
                {
                    return TRUE;
                }
            }
        }
        return FALSE;
    }
    // }}}
    /** {{{ sessWrite($wSid, $wData)
     *
     * @param   String  $wSid
     * @param   String  $wData
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessWrite($wSid = '', $wData = '')
    {
        $wData  = mysql_escape_string($wData);
        $wSql    = sprintf("UPDATE `%s`.`%s` SET `%s` = '%s', `%s` = UNIX_TIMESTAMP(NOW()) WHERE `%s` = '%s';",
                        DB_NAME,
                        self::$mTblSess,
                        self::$mTblSessMap['data'],
                        $wData,
                        self::$mTblSessMap['last'],
                        self::$mTblSessMap['sid'],
                        $wSid
                );
        if (!PEAR::isError(self::$mDb->query($wSql)))
        {
            return TRUE;
        }
        return FALSE;
    }
    // }}}
    /** {{{ sessDestroy($wSid)
     *
     * @param   String  $wSid
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessDestroy($wSid = '')
    {
        $wSql    = sprintf("DELETE FROM `%s`.`%s` WHERE `%s` = '%s';",
                        DB_NAME,
                        self::$mTblSess,
                        $wSid
                );
        if (!PEAR::isError(self::$mDb->query($wSql)))
        {
            return TRUE;
        }
        return FALSE;
    }
    // }}}
    /** {{{ sessGc()
     *
     * @param   NULL
     *
     * @return  Bool    TRUE/FALSE
     */
    public function sessGc()
    {
        global $db;
        //计算出过期时间
        $last   = time() - self::$mSessMaxTime;
        $wSql    = sprintf("DELETE FROM `%s`.`%s` WHERE `%s` < $last;", DB_NAME, self::$mTblSess, self::$mTblSessMap['last']);
        if (!PEAR::isError(self::$mDb->query($wSql)))
        {
            return TRUE;
        }
        return FALSE;
    }
    // }}}
    /** {{{ initSess()
     *
     * @param   NULL
     *
     * @return  Bool    TRUE/FALSE
     */
    public function initSess()
    {
        $domain = '';
        //不使用 GET/POST 变量方式
        ini_set('session.use_trans_sid',    0);
        //设置垃圾回收最大生存时间
        ini_set('session.gc_maxlifetime',   SESS_LIFTTIME);
        //使用 COOKIE 保存 SESSION ID 的方式
        ini_set('session.use_cookies',      1);
        ini_set('session.cookie_path',      '/');
        //多主机共享保存 SESSION ID 的 COOKIE
        ini_set('session.cookie_domain',    $domain);
        //将 session.save_handler 设置为 user,而不是默认的 files
        session_module_name('user');
        //定义 SESSION 各项操作所对应的方法名:
        session_set_save_handler(
                array('Usess', 'sessOpen'),   //对应于静态方法 My_Sess::open(),下同。
                array('Usess', 'sessClose'),
                array('Usess', 'sessRead'),
                array('Usess', 'sessWrite'),
                array('Usess', 'sessDestroy'),
                array('Usess', 'sessGc')
                );
        session_start();
        return TRUE;
    }
    // }}}
}//end class
}//end define
$sess   = new Usess;
$sess->initSess();
?>
以上代码在 php5.20 中测试通过。


本文转自叶金荣51CTO博客,原文链接:http://blog.51cto.com/imysql/310479,如需转载请自行联系原作者
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
3月前
|
Unix 应用服务中间件 索引
服务器数据恢复—LUN映射出错导致文件系统共享冲突的数据恢复案例
SUN光纤存储系统中有一组由6个硬盘组建的RAID6,划分为若干LUN,MAP到跑不同业务的服务器上,这些服务器上运行的是SOLARIS操作系统。 服务器不存在物理故障。由于公司业务变化,需要增加一台服务器跑新的应用。服务器管理员在原服务器在线的状态下,将其中一个lun映射到一台新服务器上。实际上,这个刚映射过去的卷已经map到了solaris生产系统上的某个lun上了。映射到新服务器后,服务器对这个卷进行初始化的操作,原solaris系统上的磁盘报错,重启服务器后这个卷已经无法挂载。 服务器管理员寻求sun原厂工程师的帮助。sun工程师检测后执行了fsck操作。执行完成后文件系统挂载成功。查
|
3月前
|
关系型数据库 MySQL PHP
PHP和Mysql前后端交互效果实现
本文介绍了使用PHP连接MySQL数据库的基本函数及其实现案例。内容涵盖数据库连接、选择数据库、执行查询、获取结果等常用操作,并通过用户登录和修改密码的功能实例,展示了PHP与MySQL的交互过程及代码实现。
275 0
PHP和Mysql前后端交互效果实现
|
7月前
|
弹性计算 Ubuntu Linux
阿里云服务器镜像怎么选?公共/自定义/共享/云市场/社区镜像区别与适用场景梳理
在购买阿里云服务器的过程中,选择合适的镜像(即云服务器的操作系统)是至关重要的一步。阿里云服务器镜像涵盖了公共镜像、自定义镜像、共享镜像、云市场镜像(镜像市场)和社区镜像等多种类型,对于新手用户来说,面对这些不同类型的镜像,往往会感到困惑,不知道它们之间的区别,更不知道如何根据自身需求进行选择。本文为大家解析这些镜像的特点、区别,并为大家提供选择参考。
1311 60
|
8月前
|
关系型数据库 MySQL Linux
查看Linux、Apache、MySQL、PHP版本的技巧
以上就是查看Linux、Apache、MySQL、PHP版本信息的方法。希望这些信息能帮助你更好地理解和使用你的LAMP技术栈。
392 17
|
9月前
|
关系型数据库 MySQL PHP
源码编译安装LAMP(HTTP服务,MYSQL ,PHP,以及bbs论坛)
通过以上步骤,你可以成功地在一台Linux服务器上从源码编译并安装LAMP环境,并配置一个BBS论坛(Discuz!)。这些步骤涵盖了从安装依赖、下载源代码、配置编译到安装完成的所有细节。每个命令的解释确保了过程的透明度,使即使是非专业人士也能够理解整个流程。
242 18
|
10月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
393 25
|
10月前
|
应用服务中间件 PHP nginx
当你的nginx服务器和php服务器不在一起的时候,这个nginx 的root目录问题
两个服务器的网站代码目录需要对齐,docker容器里面也是一样
|
12月前
|
SQL 关系型数据库 MySQL
PHP与MySQL的高效交互:从基础到实践####
本文深入探讨了PHP与MySQL数据库之间的高效交互技术,涵盖了从基础连接到高级查询优化的全过程。不同于传统的摘要概述,这里我们直接以一段精简代码示例作为引子,展示如何在PHP中实现与MySQL的快速连接与简单查询,随后文章将围绕这一核心,逐步展开详细讲解,旨在为读者提供一个从入门到精通的实战指南。 ```php <?php // 数据库配置信息 $servername = "localhost"; $username = "root"; $password = "password"; $dbname = "test_db"; // 创建连接 $conn = new mysqli($se
311 31
|
12月前
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发:从基础到实践####
本文将深入探讨PHP与MySQL的结合使用,展示如何构建一个动态网站。通过一系列实例和代码片段,我们将逐步了解数据库连接、数据操作、用户输入处理及安全防护等关键技术点。无论您是初学者还是有经验的开发者,都能从中获益匪浅。 ####
|
3月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
135 3

热门文章

最新文章

推荐镜像

更多