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[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=usersession_set_save_handler("open", "close", "read", "write", "destroy", "gc");session_start();//session_destroy();?>
sessiondb.class.php
<?phpclass 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>";}}}}?>