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.多次打开并且写入,这个不建议使用,比较打开文件,写入都是耗费时间的。如果能一次搞定的,就不要做多次了。 除非,中间执行很耗时的业务。