首页 > 技术文章 > session的封装使用

wanghjun 2018-05-23 09:40 原文

session默认是以文件的方式存储在服务器的,当用户量大的时候,生成的文件会很多,对服务器进行读取和写入时,会大量消耗服务器资源,会导致服务器缓慢,出现拒绝等情况.

session可以使用数据库的方式(推荐memory引擎)和memcache方式存储(discuz使用的就是数据库方式进程存储)

 

官方提供了一个方法函数session_set_save_handler(); 在session_start前使用:

使用该方法函数必须实现的5个方法:

open 初始化一些数据和连接session驱动
close 关闭session驱动
read 读取session数据
write 写入session数据
destroy 销毁session数据
gc 垃圾销毁

 

1.面向过程的方法:

<?php
function open($save_path, $session_name)
{
  echo __FUNCTION__,"<br />";
  return(true);
}
function close()
{
  echo __FUNCTION__,"<br />";
  return(true);
}
function read($id)
{
  echo __FUNCTION__,"<br />";
}
function write($id, $sess_data)
{
  echo __FUNCTION__,"<br />";
  return(true);
}
function destroy($id)
{
  echo __FUNCTION__,"<br />";
  return(true);
}
function gc($maxlifetime)
{
  echo __FUNCTION__,"<br />";
  return true;
}
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
register_shutdown_function('test');

function test()
{
  echo __FUNCTION__,"<br />";
}
session_start();
//session_commit();
$_SESSION['a'] = 1; echo 'aaaaa',"<br />";

  

 

2.面向对象(可以参考tinkphp的session驱动):

<?php


$handler = new SessionMemcache(); //定义的session类驱动
//该类必须包含的几个方法
session_set_save_handler( array($handler, 'open'),  array($handler, 'close'), array($handler, 'read'),array($handler, 'write'), array($handler, 'destroy'), array($handler, 'gc'));

Class SessionMemcache{
    //memcache对象
    private $mem;
    //SESSION有效时间
    private $expire;
    private $pre = ''; //session前缀
    private $time = 0; //session有效期
    //连接memcached和初始化一些数据
    public function open($path,$name){
        $this->expire = $this->time ? $this->time :ini_get('session.gc_maxlifetime');
        $this->mem = new Memcache;
        return $this->mem->connect('192.168.0.62', 11211);
    }
    //关闭memcache服务器
    public function close(){
        return $this->mem->close();
    }
    //读取数据
    public function read($id){
        $id = $this->pre.$id;
        $data = $this->mem->get($id);
        return $data ? $data :'';
    }
    //存入数据
    public function write($id,$data){
        $id = $this->pre.$id;
        //$data = addslashes($data);
        return $this->mem->set($id,$data,0,$this->expire);
    }
    //销毁数据
    public function destroy($id){
        $id = $this->pre.$id;
        return $this->mem->delete($id);
    }
    //垃圾销毁
    public function gc(){
        return true;
    }
}

session_start();
$_SESSION['a'] = 1; //session赋值
echo $_SESSION['a']; //session取值

  

register_shutdown_function('session_write_close');
使用session_set_save_handler(),得记得使用 'register_shutdown_function',手册中是这样解释的:
在脚本执行完毕之后,PHP 内部会清除对象, 所以有可能不调用 write 和 close 回调函数。 这样可能会引发非预期的行为,所以当使用对象作为会话保存管理器时, 需要通过注册 shutdown 回调函数来规避风险。 通常,你可以通过
调用 register_shutdown_function() 函数 来注册 'session_write_close' 回调函数。
 
 
其他注解:
启动”session_start” 会自动执行,open,read函数,然后页面执行完,会执行shutdown函数,最后会把session写入进去,然后执行close关闭文件。从session_start 到页面结束,会一直锁定文件或者保持连接的。
 
session_commit();的使用:
session_start();
session_commit();
执行commit后,直接会调用,wirte,close操作。最后执行register_shutdown_function()注册的函数
 
总结:
1.只读取session页面,建议打开后,就直接commit,这是$_SESSION变量已经生成了。
2.有对session进行写入页面,建议修改完$_SESSION后,直接调用commit
3.多次打开并且写入,这个不建议使用,比较打开文件,写入都是耗费时间的。如果能一次搞定的,就不要做多次了。 除非,中间执行很耗时的业务。
 
 
 
 
 
 
 
 

推荐阅读