php学习笔记(二十八)session的高级管理(基于数据库和memcache的)
session有几种使用方式1.基于cookie的
2.基于url的sid字符串的
3.存储到数据库中的
4.存储的memcache中的(效率最好的)
sessionHighsave.php
<?php
/**
* 一:session高级会话控制
* 1.解决跨机保存session
* 在linux使用nf或者samba
* 使用数据库来实现
* memcache来保存会话
*
* session_set_save_handler()
*
*2.解决在线用户信息的统计
*
* 二:常用的session配置选项
* session.name
* session.use_trans_sid在不使用cookie的情况下,将所有链接加入sessionID
* session.save_path存放路径
*
* session.use_cookies是否使用cookie
* session.cookie_pathcookie存放的位置
* session.cookie_domaincookie的域名
* session.cookie_lifetimecookie的存活时间
*
* gc:垃圾回收的意思
* session.gc_maxlifetime单位是秒不会自动清除,需要指定下两个参数
* 以下两个合起来是启动垃圾回收器进程管理的概率用个的
* 在初始化时(session_start)进行垃圾回收的概率
* session.gc_probability=1
* session.gc_divisor=100
*
* session.save_handler来控制session存储:files、memcache、user等
*
* 三、使用session.save_handler()函数的使用
*
*/
include 'sessionmm.class.php';
//也可以直接换成文件方式的如下:
//include 'session.php';
//也可以直接换成数据库方式的如下:
//include 'sessiondb.class.php';
$_SESSION["isLogin"]=1;
$_SESSION["username"]="admin";
$_SESSION["uid"]="333";
echo "=================================".$_SESSION["username"];
echo session_name().session_id()."<br>";
?>
sessionHighget.php
<?php
include 'sessionmm.class.php';
//也可以直接换成文件方式的如下:
//include 'session.php';
//也可以直接换成数据库方式的如下:
//include 'sessiondb.class.php';
echo "=================================";
print_r($_SESSION);
echo "<br>";
echo session_name().session_id()."<br>";
?>
sessionHighdestroy.php
<?php
include 'sessionmm.class.php';
//也可以直接换成文件方式的如下:
//include 'session.php';
//也可以直接换成数据库方式的如下:
//include 'sessiondb.class.php';
$_SESSION = array();
if (isset($_COOKIE))
setcookie(session_name(),"",time()-100,"/");
session_destroy();
echo session_name().session_id()."<br>";
?>
session.php
<?php
/**
* 在运行
* session_start
* 方法时执行
*/
function open($save_path,$session_name){
echo "open() <br>";
global $sess_save_path;
$sess_save_path = $save_path;
echo $save_path.": $session_name <br>";
return true;
}
/**
* 在运行
* session_write_close()
* session_destroy()
* 方法时执行
*/
function close(){
echo "close() <br>";
return true;
}
/**
* 在运行
* session_start
* $_SESSION
* 方法时执行(读取session数据到$_SESSION中)
*/
function read($id){
echo "read() <br>";
global $sess_save_path;
$sess_file = $sess_save_path."/sid_".$id;
return (string)@file_get_contents($sess_file);
}
/**
* 在运行结束时
* session_write_close()
* 方法强制提交SESSSION数据时执行
*/
function write($id,$sess_data){
echo "write() <br>";
global $sess_save_path;
$sess_file = $sess_save_path."/sid_".$id;
if ($fp = @fopen($sess_file, "w")) {
$return = fwrite($fp, $sess_data);
fclose($fp);
return $return;
}else {
return false;
}
}
/**
* 在运行结束时
* session_destroy()
* 方法时执行
*/
function destroy($id){
echo "destroy() <br>";
global $sess_save_path;
$sess_file = $sess_save_path."/sid_".$id;
return @unlink($sess_file);
}
/**
* session.gc_probability=1
* session.gc_divisor=100
* 属性共同决定的
* open、read、session_start也会执行gc
*/
function gc($maxlifetime){
echo "gc() <br>";
global $sess_save_path;
foreach (glob($sess_save_path."/sid_*") as $filename){
if ((fileatime($filename)+$maxlifetime)<time()){
@unlink($filename);
}
};
}
//使用此函数,需要ini中的session.save_handler=user
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
session_start();
//session_destroy();
?>
sessiondb.class.php
<?php
class Session{
private static $handler = null;
private static $ip = null;
private static $lifetime = null;
private static $time = null;
private static function init($handler){
self::$handler=$handler;
self::$ip = !empty($_SESSION["REMOTE_ADDR"])?$_SESSION["REMOTE_ADDR"]:"unknow";
self::$lifetime = ini_get("session.gc_maxlifetime");
self::$time = time();
}
static function start(PDO $pdo){
self::init($pdo);
//如果是面向对象的,需要传递数组参数,第一个参数是类名,第二个参数是方法
session_set_save_handler(
//__CLASS__表示本类;为防止以后变类名需要修改代码
array(__CLASS__,"open"),
array(__CLASS__,"close"),
array(__CLASS__,"read"),
array(__CLASS__,"write"),
array(__CLASS__,"destroy"),
array(__CLASS__,"gc"));
session_start();
}
public static function select($PHPSESSID){
$sql = "select * from sessiondb where PHPSESSID = ?";
$stmt = self::$handler->prepare($sql);
$stmt->execute(array($PHPSESSID));
return $stmt;
}
public static function open($save_path,$session_name){
return true;
}
public static function close(){
return true;
}
/**
* 在运行
* session_start
* $_SESSION
* 方法时执行(读取session数据到$_SESSION中)
*/
public static function read($PHPSESSID){
$stmt = self::select($PHPSESSID);
if (!($result = $stmt->fetch(PDO::FETCH_ASSOC))){
return '';
}
if (self::$ip != $result["client_ip"]||(($result["update_time"]+self::$lifetime)<self::$time)){
self::destroy($PHPSESSID);
return '';
}
return $result['data'];
}
/**
* 在运行结束时
* session_write_close()
* 方法强制提交SESSSION数据时执行
*/
public static function write($PHPSESSID,$data){
$stmt = self::select($PHPSESSID);
if ($result = $stmt->fetch(PDO::FETCH_ASSOC)){
//控制30秒才进行更新
if ($result['data']!=$data||self::$time>($result["update_time"]+30)){
$sql = "update sessiondb set update_time=?,data=? where PHPSESSID=?";
$stm = self::$handler->prepare($sql);
$stm->execute(array(self::$time,$data,$PHPSESSID));
return '';
}
}else{
if (!empty($data)){
$sql = "insert into sessiondb(PHPSESSID,update_time,client_ip,data) values(?,?,?,?)";
$sth = self::$handler->prepare($sql);
$sth->execute(array($PHPSESSID,self::$time,self::$ip,$data));
}
}
return true;
}
/**
* 在运行结束时
* session_destroy()
* 方法时执行
*/
public static function destroy($PHPSESSID){
$sql = "delete from sessiondb where PHPSESSID = ?";
$stmt = self::$handler->prepare($sql);
$stmt->execute(array($PHPSESSID));
return true;
}
/**
* session.gc_probability=1
* session.gc_divisor=100
* 属性共同决定的
* open、read、session_start也会执行gc
*/
private static function gc($maxlifetime){
$sql = "delete from sessiondb where update_time < ?";
$stmt = self::$handler->prepare($sql);
$stmt->execute(array(self::$time-$maxlifetime));
return true;
}
}
try {
$pdo = new PDO("mysql:host=localhost;dbname=hibernate", "root", "root");
}catch (PDOException $e){
echo $e->getMessage();
}
Session::start($pdo);
?>
sessionmm.class.php
<?php
/**
* 如果不想写类,可用配置文件修改
* session.save_handler=memcache;
* session.save_path="tcp://localhost:11211","tcp:192.168.1.123:11211";
* 这样可以达到最快的修改方式,但是不容易控制
*
*/
class MemSession{
private static $handler = null;
private static $ip = null;
private static $lifetime = null;
private static $time = null;
//指定不同项目的不同前缀
const MS = "session_";
private static function init($handler){
self::$handler=$handler;
self::$ip = !empty($_SESSION["REMOTE_ADDR"])?$_SESSION["REMOTE_ADDR"]:"unknow";
self::$lifetime = ini_get("session.gc_maxlifetime");
self::$time = time();
}
static function start(Memcache $memcache){
self::init($memcache);
//如果是面向对象的,需要传递数组参数,第一个参数是类名,第二个参数是方法
session_set_save_handler(
//__CLASS__表示本类;为防止以后变类名需要修改代码
array(__CLASS__,"open"),
array(__CLASS__,"close"),
array(__CLASS__,"read"),
array(__CLASS__,"write"),
array(__CLASS__,"destroy"),
array(__CLASS__,"gc"));
session_start();
}
private static function session_key($PHPSESSID){
return self::MS.$PHPSESSID;
}
public static function select($PHPSESSID){
$sql = "select * from sessiondb where PHPSESSID = ?";
$stmt = self::$handler->prepare($sql);
$stmt->execute(array($PHPSESSID));
return $stmt;
}
public static function open($save_path,$session_name){
return true;
}
public static function close(){
return true;
}
/**
* 在运行
* session_start
* $_SESSION
* 方法时执行(读取session数据到$_SESSION中)
*/
public static function read($PHPSESSID){
$out = self::$handler->get(self::session_key($PHPSESSID));
if ($out==false||$out==null)return '';
return $out;
}
/**
* 在运行结束时
* session_write_close()
* 方法强制提交SESSSION数据时执行
*/
public static function write($PHPSESSID,$data){
$method = $data?'set':'replace';
return self::$handler->$method(self::session_key($PHPSESSID),$data,MEMCACHE_COMPRESSED,self::$lifetime);
}
/**
* 在运行结束时
* session_destroy()
* 方法时执行
*/
public static function destroy($PHPSESSID){
return self::$handler->delete(self::session_key($PHPSESSID));
}
/**
* session.gc_probability=1
* session.gc_divisor=100
* 属性共同决定的
* open、read、session_start也会执行gc
*/
private static function gc($maxlifetime){
//memcached中set的时候就已经设置了时间;所以不需要来实现gc方法了
return true;
}
}
$memcache = new Memcache;
$memcache->connect("localhost",11211) or die("could not connect");
MemSession::start($memcache);
?>
memcache.php(用来查询memcache服务器中的存储数据)
<?php
/**
* 获取所有的memcached数据
* 有时候查不出来,不清楚原因
*/
$mem = new Memcache;
$host = "localhost";
$post = 11211;
$mem->connect($host,$post);
$items = $mem->getExtendedStats("items");
$items = $items["$host:$post"]["items"];
foreach ($items as $value){
foreach ($value as $item){
$number = $item["number"];
$arr = $mem->getExtendedStats("cachedump",$number,0);
$line = $arr["$host:$post"];
if (is_array($line)&&count($line)>0){
foreach ($line as $key=>$value){
echo $key."=>";
print_r($mem->get($key));
echo "<br>";
}
}
}
}
?>
页:
[1]