我們知道,session是一種會話技術,用來實現跨腳本共享數據。
在之前的php會話技術中我們介紹過,session是存放在服務器端的文件里的,因此session有可能因為文件數量過多,會在查詢session文件以及讀取的時候產生壓力。一般我們有三種解決方案
1.使用文件分層(缺點:I/O操作是系統的一個瓶頸,即使分層也不能避免此問題)
2.將session放入數據庫
3.將session放在內存中(非關系性數據庫)(缺點:對服務器內存要求教高)
因此我們選用一個折中的辦法,將session存入mysql數據庫,也就是我們要講的重點,
session入庫技術:
要實現session入庫,首先我們要了解session 機制:
什么是session機制:
在php中,session可以理解為一套單獨的小系統,在該系統中有很多關於session的處理方法,用來解決各種問題,用戶只需要在session之外,調用session_start函數(session系統的一個接口)
其他操作都是session系統幫忙去處理

由圖可知我們應該修改session機制中的session的讀取和最終的寫入。
要修改session機制要借助一個系統函數
session_set_save_handler():用來使用外部用戶定義的函數,來取代session系統本身的函數。
session_set_save_handler(開啟session機制函數,關閉session機制函數,讀取session數據函數,寫入session函數,銷毀session函數,后手過期session函數)。
因此我們要准備六個函數。
代碼實現:
<?php
//session入庫
//以為修改session機制必須借助session_set_save_handler()函數,該函數需要6個可以調用的回調函數,因此需要創建6個人對應的函數
//1.開啟session機制
function sess_open()
{
//開啟資源
//連接數據庫
mysql_connect('localhost','root','');
mysql_query('set names utf8');
mysql_query('use session');
echo __FUNCTION__,'<br/>';
}
//2.關閉session
function sess_close()
{
//關閉資源
mysql_close();
echo __FUNCTION__,'<br/>';
}
//3.讀取session
function sess_read($sess_id)
{
//從數據庫讀取數據
//根據sess_id(由系統提供)獲取數據
//讀數據時要過濾掉過期的數據
$expire=time()-ini_get('session.gc_maxlifetime');
$sql="selsct * from session where sess_id='{$sess_id}' and sess_expire>='{$expire}'";
$res=mysql_query($sql);
//得到的是一個數組
if($sess=@mysql_fetch_assoc($res))
{
//得到一個序列化后的字符串
//要進行反序列化,read只負責讀取數據,不負責加工數據
return $sess['sess_info'];
}
echo __FUNCTION__,'<br/>';
}
//4.寫入session
function sess_write($sess_id,$sess_info)
{
//向數據庫中寫入數據
$time=time();
$sql="replace into session values('{$sess_id}','{$sess_info}','{$time}')";
mysql_query($sql);
echo __FUNCTION__,'<br/>';
}
//5.銷毀session
function sess_destroy($sess_id)
{
$sql="delete from session where sess_id='{$sess_id}'";
return mysql_query($sql);
echo __FUNCTION__,'<br/>';
}
//6.回收session
function sess_gc()
{
//從數據庫刪除過期的session數據
//判斷session是否過期,過期的刪除
$expire=ini_get('session.gc_maxlifetime');
//得到最遲的時間,在$expire之前的都是過期的
$expire=time()-$expire;
$sql="delete from session where sess_expire < '{expire}'";
return mysql_query($sql);
echo __FUNCTION__,'<br/>';
}
//使用session_set_save_handler()修改session機制
session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_gc');
//想要使用session,必須要用session_start()來開啟
session_start();
$_SESSION['name']='wangqixing';
$_SESSION['age']='23';
//session_destroy();
//session入庫
//以為修改session機制必須借助session_set_save_handler()函數,該函數需要6個可以調用的回調函數,因此需要創建6個人對應的函數
//1.開啟session機制
function sess_open()
{
//開啟資源
//連接數據庫
mysql_connect('localhost','root','');
mysql_query('set names utf8');
mysql_query('use session');
echo __FUNCTION__,'<br/>';
}
//2.關閉session
function sess_close()
{
//關閉資源
mysql_close();
echo __FUNCTION__,'<br/>';
}
//3.讀取session
function sess_read($sess_id)
{
//從數據庫讀取數據
//根據sess_id(由系統提供)獲取數據
//讀數據時要過濾掉過期的數據
$expire=time()-ini_get('session.gc_maxlifetime');
$sql="selsct * from session where sess_id='{$sess_id}' and sess_expire>='{$expire}'";
$res=mysql_query($sql);
//得到的是一個數組
if($sess=@mysql_fetch_assoc($res))
{
//得到一個序列化后的字符串
//要進行反序列化,read只負責讀取數據,不負責加工數據
return $sess['sess_info'];
}
echo __FUNCTION__,'<br/>';
}
//4.寫入session
function sess_write($sess_id,$sess_info)
{
//向數據庫中寫入數據
$time=time();
$sql="replace into session values('{$sess_id}','{$sess_info}','{$time}')";
mysql_query($sql);
echo __FUNCTION__,'<br/>';
}
//5.銷毀session
function sess_destroy($sess_id)
{
$sql="delete from session where sess_id='{$sess_id}'";
return mysql_query($sql);
echo __FUNCTION__,'<br/>';
}
//6.回收session
function sess_gc()
{
//從數據庫刪除過期的session數據
//判斷session是否過期,過期的刪除
$expire=ini_get('session.gc_maxlifetime');
//得到最遲的時間,在$expire之前的都是過期的
$expire=time()-$expire;
$sql="delete from session where sess_expire < '{expire}'";
return mysql_query($sql);
echo __FUNCTION__,'<br/>';
}
//使用session_set_save_handler()修改session機制
session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_gc');
//想要使用session,必須要用session_start()來開啟
session_start();
$_SESSION['name']='wangqixing';
$_SESSION['age']='23';
//session_destroy();