php中使用session_set_save_handler()函数把session保存到MySQL数据库实例


Posted in PHP onNovember 06, 2014

PHP保存session默认的是采用的文件的方式来保存的,这仅仅在文件的空间开销很小的windows上是可以采用的,但是如果我们采用uinx或者是liux上的文件系统的时候,这样的文件系统的文件空间开销是很大的,然而session是要时时刻刻的使用的,大量的用户就要创建很多的session文件,这样对整个的服务器带来性能问题。

另一方面,如果服务器起采用群集的方式的话就不能保持session的一致性,所以我们就绪要采用数据库的方式来保存session,这样,不管有几台服务器同时使用,只要把他们的session保存在一台数据库服务器上就可以保证session的完整了,具体如何来实现请继续看下去。

PHP保存session默认的情况下是采用的文件方式来保存的,我们在PHP的配制文件PHP.ini中可以看到这样的一行:

session.save_handler="files"

这样的意思就是采用文件来保存session 的,要采用数据库来保存的话,我们需要修改成用户模式,改成
session.save_handler="use"

就可以了,但是,这仅仅是说明我门没有采用文件的方式存储session,我们还要选择数据库和建立数据库的表。

建立数据库和数据库的表结构,我们可以采用PHP可以使用的任何的数据库,因为PHP和mysql的结合最好,我就使用mysql来做示例,当然根据你的需要可以改称别的数据库。

创建数据库

create database 'session';

创建表结构
create table 'session'( id char(32) not null , 'user 'char(30), data char(3000) ,primary key ('id') );

PHP保存session编写PHP文件
<?php

$con = mysql_connect("127.0.0.1", "user" , "pass");

mysql_select_db("session");

function open($save_path, $session_name) {

 return(true);

}

function close() {

 return(true);

}

function read($id) {

 if ($result = mysql_query("select * from session where id='$id'")) {

  if ($row = mysql_felth_row($result)) {

   return $row["data"];

  }

 } else {

  return "";

 }

}

function write($id, $sess_data) {

 if ($result = mysql_query("update session set data='$sess_data' where id='$id'")) {

  return true;

 } else {

  return false;

 }

}

function destroy($id) {

 if ($result = mysql_query("delete * from session where id='$id'")) {

  return true;

 } else {

  return false;

 }

}

function gc($maxlifetime) {

 return true;

}

session_set_save_handler("open", "close", "read", "write", "destroy", "gc");

session_start();

// proceed to use sessions normally

保存成为session_user_start.php。

现在我们的PHP保存session的工作就已经完成了,只要你在需要在使用session的时候,把session_user_start.php包含进来.注意,这个文件一定要在文件的第一行包含,然后就像使用文件的session一样的方法使用就可以了。

以上仅仅是个简单教程,在实际的应用中,可以对它封装得更专业些,参考代码如下:

SessionMysql.class.php

<?php

/**

 * SessionMysql 数据库存储类

 */
defined('IN_QIAN') or exit('Access Denied');
class SessionMysql {
 public $lifetime = 1800; // 有效期,单位:秒(s),默认30分钟

 public $db;

 public $table;
 /**

  * 构造函数

  */

 public function __construct() {

  $this->db = Base::loadModel('SessionModel');

  $this->lifetime = Base::loadConfig('system', 'session_lifetime');

  session_set_save_handler(

   array(&$this, 'open'),  // 在运行session_start()时执行

   array(&$this, 'close'),  // 在脚本执行完成 或 调用session_write_close() 或 session_destroy()时被执行,即在所有session操作完后被执行

   array(&$this, 'read'),  // 在运行session_start()时执行,因为在session_start时,会去read当前session数据

   array(&$this, 'write'),  // 此方法在脚本结束和使用session_write_close()强制提交SESSION数据时执行

   array(&$this, 'destroy'), // 在运行session_destroy()时执行

   array(&$this, 'gc')   // 执行概率由session.gc_probability 和 session.gc_divisor的值决定,时机是在open,read之后,session_start会相继执行open,read和gc

  );

  session_start(); // 这也是必须的,打开session,必须在session_set_save_handler后面执行

 }

 /**

  * session_set_save_handler open方法

  *

  * @param $savePath

  * @param $sessionName

  * @return true

  */

 public function open($savePath, $sessionName) {

  return true;

 }

 /**

  * session_set_save_handler close方法

  *

  * @return bool

  */

 public function close() {

  return $this->gc($this->lifetime);

 }

 /**

  * 读取session_id

  *

  * session_set_save_handler read方法

  * @return string 读取session_id

  */

 public function read($sessionId) {

  $condition = array(

   'where' => array(

    'session_id' => $sessionId

   ),

   'fields' => 'data'

  );

  $row = $this->db->fetchFirst($condition);

  return $row ? $row['data'] : '';

 }

 /**

  * 写入session_id 的值

  *

  * @param $sessionId 会话ID

  * @param $data 值

  * @return mixed query 执行结果

  */

 public function write($sessionId, $data) {

  $userId = isset($_SESSION['userId']) ? $_SESSION['userId'] : 0;

  $roleId = isset($_SESSION['roleId']) ? $_SESSION['roleId'] : 0;

  $grouId = isset($_SESSION['grouId']) ? $_SESSION['grouId'] : 0;

  $m = defined('ROUTE_M') ? ROUTE_M : '';

  $c = defined('ROUTE_C') ? ROUTE_C : '';

  $a = defined('ROUTE_A') ? ROUTE_A : '';

  if (strlen($data) > 255) {

   $data = '';

  }

  $ip = get_ip();

  $sessionData = array(

   'session_id' => $sessionId,

   'user_id'  => $userId,

   'ip'   => $ip,

   'last_visit' => SYS_TIME,

   'role_id'  => $roleId,

   'group_id'  => $grouId,

   'm'    => $m,

   'c'    => $c,

   'a'    => $a,

   'data'   => $data,

  );

  return $this->db->insert($sessionData, 1, 1);

 }

 /**

  * 删除指定的session_id

  *

  * @param string $sessionId 会话ID

  * @return bool

  */

 public function destroy($sessionId) {

  return $this->db->delete(array('session_id' => $sessionId));

 }

 /**

  * 删除过期的 session

  *

  * @param $lifetime session有效期(单位:秒)

  * @return bool

 */

 public function gc($lifetime) {

  $expireTime = SYS_TIME - $lifetime;

  return $this->db->delete("`last_visit`<$expireTime");

 }

}

在系统文件的某个地方,实例化这个类即可!

new SessionMysql();
PHP 相关文章推荐
3种平台下安装php4经验点滴
Oct 09 PHP
使PHP自定义函数返回多个值
Nov 26 PHP
php 随机数的产生、页面跳转、件读写、文件重命名、switch语句
Aug 07 PHP
php feof用来识别文件末尾字符的方法
Aug 01 PHP
PHP版国家代码、缩写查询函数代码
Aug 14 PHP
zf框架的session会话周期及次数限制使用示例
Mar 13 PHP
Zend Framework教程之Resource Autoloading用法实例
Mar 08 PHP
Zend Framework自定义Helper类相关注意事项总结
Mar 14 PHP
Symfony2函数用法实例分析
Mar 18 PHP
PHP文件管理之实现网盘及压缩包的功能操作
Sep 20 PHP
PHP7匿名类的用法示例
Apr 05 PHP
Laravel Validator 实现两个或多个字段联合索引唯一
May 08 PHP
php中常见的sql攻击正则表达式汇总
Nov 06 #PHP
php中实现记住密码下次自动登录的例子
Nov 06 #PHP
php网站被挂木马后的修复方法总结
Nov 06 #PHP
调试PHP程序的多种方法介绍
Nov 06 #PHP
php实现singleton()单例模式实例
Nov 06 #PHP
php使用session二维数组实例
Nov 06 #PHP
php函数serialize()与unserialize()用法实例
Nov 06 #PHP
You might like
example2.php
2006/10/09 PHP
PHP中文URL编解码(urlencode()rawurlencode()
2010/07/03 PHP
PHP开发中常见的安全问题详解和解决方法(如Sql注入、CSRF、Xss、CC等)
2014/04/21 PHP
PHP文件读写操作相关函数总结
2014/11/18 PHP
php 将json格式数据转换成数组的方法
2018/08/21 PHP
有趣的javascript数组定义方法
2010/09/10 Javascript
jQuery实现数字加减效果汇总
2014/12/16 Javascript
jQuery获取上传文件的名称的正则表达式
2015/05/21 Javascript
js实现文字垂直滚动和鼠标悬停效果
2015/12/31 Javascript
浅析创建javascript对象的方法
2016/05/13 Javascript
基于javascript实现最简单的选项卡切换效果
2016/05/16 Javascript
AngularJS操作键值对象类似java的hashmap(填坑小结)
2016/11/12 Javascript
javascript实现页面滚屏效果
2017/01/17 Javascript
微信小程序实现带刻度尺滑块功能
2017/03/29 Javascript
JavaScript之排序函数_动力节点Java学院整理
2017/06/30 Javascript
动态创建Angular组件实现popup弹窗功能
2017/09/15 Javascript
Vue-router 类似Vuex实现组件化开发的示例
2017/09/15 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
vue与原生app的对接交互的方法(混合开发)
2018/11/28 Javascript
Vue实现拖放排序功能的实例代码
2019/07/08 Javascript
vue中实现点击按钮滚动到页面对应位置的方法(使用c3平滑属性实现)
2019/12/29 Javascript
推荐下python/ironpython:从入门到精通
2007/10/02 Python
Python提示[Errno 32]Broken pipe导致线程crash错误解决方法
2014/11/19 Python
Python随机生成一个6位的验证码代码分享
2015/03/24 Python
Python中的with...as用法介绍
2015/05/28 Python
Python base64编码解码实例
2015/06/21 Python
Ubuntu下创建虚拟独立的Python环境全过程
2017/02/10 Python
rabbitmq(中间消息代理)在python中的使用详解
2017/12/14 Python
python3读取csv和xlsx文件的实例
2018/06/22 Python
mac安装pytorch及系统的numpy更新方法
2018/07/26 Python
python3 下载网络图片代码实例
2019/08/27 Python
用python求一重积分和二重积分的例子
2019/12/06 Python
基于PyInstaller各参数的含义说明
2021/03/04 Python
班级入场式解说词
2014/02/01 职场文书
我们的节日国庆活动方案
2014/08/19 职场文书
Pandas 数据编码的十种方法
2022/04/20 Python