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_path		cookie存放的位置
 * session.cookie_domain	cookie的域名
 * session.cookie_lifetime	cookie的存活时间
 * 
 * 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[session_name()]))
	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>";
				}
			}
		}
	}
?>



你可能感兴趣的:(memcache)