第二部分(自定义)
1、 自定义sesssion存到文本。首先你要php.ini里把session_set_save_handler()选项值 设置为user,下面的自定义才会被系统调用。代码分析
<?php
//声明的变量用来保存session文件在服务器中保存的路径
$sess_save_path="";
这个函数在运行session_start()时执行,系统会自动把第一个
赋值为session.save_path的选项值,把第二个赋值为sesssion的名称(系统会自动传入,只需将参数摆好顺序,取啥名没影响),返回值为true表示函数执行成功。
function open($save_path,$session_name){
global$sess_save_pat;
$sess_save_pat=$save_pat;
returntrue;
}
//下面这个函数在session操作完后被执行,本例没用到,直接返回true
function close(){
returntrue;
}
// 下面这个在运行session_start()时执行,在开启对话时去read当前session数据并写入$_session变量,系统会自动传递为当前用户分配的session id为这个函数的参数,返回保存session所有序列化的字符串信息。
function read($id){
global$sess_save_pat;
$sess_file="$sess_save_path\sess_$id";
return(string) @file_get_contents($sess_file);
}
//该函数在脚本结束和对$_session变量赋值时执行,系统会自动为第一个参数赋值为为当前用户分配的sessionid,第二个就是所有串行化好的session信息字符串。
function write($id,$sess_data){
global$sess_save_pat;
$sess_file="$sess_save_pat\sess_$id";
if($fp=@fopen($sess_file,"w")){
$return=fwrite($fp,$sess_data);//其实这个函数就是返回的写入了多少个字符。
fclose($fp);
return$return;
}else{
returnfalse;
}
}
//在运行session_destroy()时执行,系统会自动把第一个参数赋值为为这位用户分配好的sessionid
function destroy($id){
global$sess_save_pat;
$sess_file="$sess_save_pat\sess_$id";
return(@unlink($sess_file));//删除文件嘛
}
垃圾会收程序启动时会执行,系统会自动将php.ini中的session.gc_maxlifetime选项值传递给该参数。成功时返回true
function gc($maxlifetime){
global$sess_save_pat;
foreach(glob("$sess_save_path\sess_*")as $filename){// glob() 函数返回匹配指定模式的文件名或目录。 该函数返回一个包含有匹配文件 / 目录的数组。
if(filemtime($filename)+$maxliftime<time()){
@unlink($filename);
}
}
returntrue;
}
session_set_save_handler("open","close","read","write","destroy","gc");就调用以上函数了
session_start();
/* 以下代码中应用sesssion方式不变*/
?>
2、 自定义session存到数据库中。代码如下:
<?php
class DBsession{
protected static $pdo=null;//用PDO处理
protected static $ua=null;//
protected static $lifetime=null;//session的生存周期
protected static $ip=null;//客户端IP,用于判断用户是否改变IP
protected static $time=null;//现在的时间点
public static function start(PDO $pdo){
self::$pdo=$pdo;//在类外创建一个pdo对象传入,并赋值
//获取客户端的代理浏览器
self::$ua=isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:'';
//获取客户端使用的IP self::$ip=!empty($_SERVER['HTTP_CLIENT_IP'])?$_SERVER['HTTP_CLIENT_IP']:(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])?$_SERVER['HTTP_X_FORWARDED_FOR']:(!empty($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'unknown'));/*第一个是常用的获取浏览器所在电脑IP(真实的),如果是用的代理浏览器,第一个就是空值,就用第二个获取真正的IP,第三个是获取代理服务器的IP(如果是用的代理服务器), 不然就是真实的IP*/
self::$lifetime=ini_get("session.gc_maxlifetime");//这个函数很巧,可以从phi.ini中获取session.gc_maxlifetime的值。
self::$time=time();
session_set_save_handler( /*本来用_CLASS_代替DBsession,没成功,因为我只用了一根_应该是__*/
array('DBsession','open'),/* 因为是回调类中的静态方法作为参数,所以每个参数需要使用数组指定静态方法所在的类*/
array(__CLASS__,'close'),
array('DBsession','read'),
array('DBsession','write'),
array('DBsession','destroy'),
array('DBsession','gc'));
session_start();//开启会话,启用数据库存储session
}
private static functionopen($path,$name){
return true;
}
public static function close(){
return true;
}
private static function read($sid){
$sql="select * from sessionwhere sid =?";
$stmt=self::$pdo->prepare($sql);
$stmt->execute(array($sid));
if(!$result=$stmt->fetch(PDO::FETCH_ASSOC)){
return '';
}
if(self::$ip!=$result['client_ip']||self::$ua!=$result['user_agent']){
self::destroy($sid);
return '';
}
return $result['data'];
}
public static function write($sid,$data){
$sql="select * from sessionwhere sid=?";
$stmt=self::$pdo->prepare($sql);
$stmt->execute(array($sid));
/*如果用户的会话信息已经存在,则去修改*/
if($result=$stmt->fetch(PDO::FETCH_ASSOC)){
if($result['data']!=$data||self::$time>($result['update_time']+30)){
$sql="update sessionset update_time=?,data=? where sid=?";
$stmt=self::$pdo->prepare($sql);
$stmt->execute(array(self::$time,$data,$sid));
}
/*如果用户的会话信息不存在,则添加一条新的*/
}else{
if(!empty($data)){
$sql="insertinto session (sid,update_time,client_ip,user_agent,data)values(?,?,?,?,?)";
$stmt=self::$pdo->prepare($sql);
$stmt->execute(array($sid,self::$time,self::$ip,self::$ua,$data));
}
}
return true;
}
public static function destroy($sid){
$sql='delete from session wheresid=?';
$stmt=self::$pdo->prepare($sql);
$stmt->execute(array($sid));
return true;
}
public static function gc($lifetime){
$sql="delete from sessionwhere updata_time<?";
$stmt=self::$pdo->prepare($sql);
$stmt->execute(array(self::$time-$lifetime));
return true;
}
}
Try{
$pdo=newPDO(“mysql:host=localhost;dbname=session”,”root”,”23456”);
}catch(PDOException$e){
Die(“连接失败;”.$e->getMessage9));
}
DBSession::start($pdo);
/*这里就和正常的session一样的用法*/
3、 使用memcached处理session信息,直接上代码了,前面看的懂,你后面肯定都能看的懂
<?php
class MEMSession{
constNS="session_";
protectedstatic $mem=null;
protectedstatic $lifetime=null;
publicstatic function start(Memcache $mem){
self::$mem=$mem;
self::$lifetime=ini_get("session.gc_maxlifetime");
session_set_save_handler(
array(__CLASS__,'open'),
array(__class__,"close"),
array(__class__,"read"),
array(__class__,"write"),
array(__class__,"destroy"),
array(__class__,"gc")
);
session_start();
}
privatestatic function open($path,$name){
returntrue;
}
publicstatic function close(){
returntrue;
}
privatestatic function read($sid){
$out=self::$mem->get(self::session_key($sid));
if($out===false||$out===null){
return'';
}
return$out;
}
publicstatic function write($sid,$data){
$method=$data?'set':'replace';
returnself::$mem->$method(self::session_key($sid),$data,MEMCACHE_COMPRESSED,self::$lifetime);
}
publicstatic function destroy($sid){
returnself::$mem->delete(self::session_key($sid));
}
privatestatic function gc($lifetime){
returntrue;
}
privatestatic function session_key($sid){
$session_key='';
if(defined("project_ns")){
$session_key.=project_ns;
}
$session_key.=self::NS.$sid;
return$session_key;
}
}
?>