搜尋
首頁後端開發php教程PHP中如何將session存入資料庫並使用

PHP中如何將session存入資料庫並使用

這篇文章要介紹給大家的內容是關於PHP中如何將session存入資料庫並使用(附代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

實例說明:

#將SESSION資料變數儲存於伺服器是端是一種較安全的做法,但是設想一下,像校內網這樣的日訪問量過億,擁有用戶幾千萬的大型網站,如果將所有用戶SESSION數據全部存儲於伺服器端,將消耗巨大的伺服器資源。所以程式設計師在製作大型網站時將SESSION儲存在伺服器端雖然安全,但卻不是最好的選擇。如果將SESSION資料儲存於資料庫中,那麼就可以減輕伺服器的壓力同時資料也是比較安全的。

相關專題推薦php session(包含圖文、影片、案例)

設計流程

首先在Mysql資料庫建立儲存SESSION的表:

表名為t_session

表結構為

PHP中如何將session存入資料庫並使用

說明:session_key:是用來存會話ID的

  • <span style="color:#3a3737;">session_data</span>:是用來存經序列化後的$_SESSION[ ]裡的值;

  • <span style="color:#3a3737;">session_time</span>:是用來存時間戳記的,這個時間戳指的是當前session在建立時的time() session的有效期限。要注意的是這 裡的session_time的類型是int,這樣可以在操作資料庫時,進行大小比較!

那麼什麼是序列化呢?

序列化 (Serialization)就是將物件的狀態資訊轉換成可以儲存或傳輸的形式的過程。在序列化期間,物件將其目前狀態寫入到臨時或持久性儲存區。以後,可以透過從儲存區讀取或反序列化物件的狀態,重新建立該物件。

比如說

$_SESSION[“user”]=”张三”
$_SESSION[“pwd”]=”zhangsan”

序列話後成為一個字串

user|s:6:"张三";pwd|s:8:"zhangsan";

其中s表示類型為string,數字表示字串長度,這樣就可以對這個字串操作了。

接下來就是正文部分了

session.save_handler 定義儲存和取得與會話關聯的資料的處理器的名字。預設為 files。如果設定為files(session.save_handler = files),則採用的是php內建機制,如果想自訂儲存方式(例如儲存到資料庫),則使用session_set_save_handler()進行自訂設定# ,我們這裡說的則是第二種。

所以我們得修改php.ini檔案裡session_set_save_handler的值,將其修改為user

########################################都圖:################

bool session_set_save_handler ( callable open# , callable $close# , callable read# , callable write , callable destroy , callable gc [, ##callable $create_sid [, callable validate_sid [, callable update_timestamp ]]] )

如果不修改,那你在使用session的時候可以不用理他,但當你修改了,你不得不面對他。這是一個很特別的函數,因為一般的函數的參數都是變量,但是該函數的參數為6個函數(後面的三個參數為可選參數,可忽略)不用怕,一個一個來:

第一個參數:  open(save_path,session_name),這裡面的兩個參數是php自動傳遞的。 save_path 在session.save_handler = files的情況下它就是session.save_path,session_name則是伺服器用來識別客戶端的會話ID,但是如果用戶自定的話,這個兩個參數都用不上,只在其中連接資料庫, open 回呼函數類似類別的建構函數,在會話開啟的時候會被呼叫。這是自動開始會話或透過呼叫 session_start() 手動開始會話之後第一個被呼叫的回呼函數。此回呼函數操作成功傳回 TRUE,反之回傳 FALSE。

第二個參數:  close(),這個函數不需要參數,用來關閉資料庫。 close 回呼函數類似於類別的析構函數。在 write 回調函數呼叫之後呼叫。當呼叫 session_write_close() 函數之後,也會呼叫 close 回呼函數。此回呼函數操作成功傳回 TRUE,反之回傳 FALSE。

第三個參數:  read($key),這裡面的參數是會話ID,php自動傳遞的,傳遞的前提是有會話ID,若無,則這個參數返回空字串。注意,若資料庫中無對應的資料一定要傳回空字串,否則報錯!如果會話中有數據,read 回呼函數必須傳回將會話資料編碼(序列化)後的字串(在此處就是從表t_session裡取出的session_data)。在自動開始會話或透過呼叫 session_start()函數手動開始會話之後,PHP 內部呼叫 read 回呼函數來取得會話資料。在呼叫 read 之前,PHP 會呼叫 open 回呼函數。 read 回呼傳回的序列化之後的字串格式必須與 write 回呼函數儲存資料 時的格式完全一致。 PHP 會自動反序列化傳回的字串並填入 $_SESSION  超級全域變數。

第四個參數:  write($key,$data), 這兩個參數也是php自動傳遞給這個函數的,$key對應會話ID,$data對應目前(因為write函數一般是在腳本執行結束後才被呼叫的)腳本被序列化處理器處理的session變數(如上文提到的$_SESSION[“user”]=”張三”$_SESSION[“pwd”] =”zhangsan”),序列化會話資料的過程由PHP 根據 session.serialize_handler 設定值來完成。序列化後的資料將和會話 ID 關聯在一起進行保存。當呼叫 read 回呼函數取得資料時,所傳回的資料必須要和 傳入 write 回呼函數的資料完全保持一致。 PHP 會在腳本執行完成或呼叫 session_write_close() 函數之後呼叫此回呼 函數。注意,在調用完此回呼函數之後,PHP 內部會呼叫 close 回呼函數。

NOTE:PHP 會在輸出流寫入完畢並且關閉之後 才呼叫 write 回呼函數, 所以在 write 回呼函數中的偵錯資訊不會輸出到瀏覽器中。如果需要在 write 回呼函數中使用偵錯輸出, 建議將偵錯輸出寫入到檔案。 

第五个参数:  destroy($key),当调用 session_destroy() 函数, 或者调用 session_regenerate_id() 函数并且设置 destroy 参数为 TRUE 时, 会调用此回调函数。用来注销session对应的SESSION键值,此回调函数操作成功返回 TRUE,反之返回 FALSE。它就是人们常常在点击注销登录的时候用到的函数。后面会有这个小细节。

第六个参数:  gc(expire_time),这个函数的参数在默认机制下就是session.gc_maxlifetime设置的session有效时间。但是,user机制下session的过期时间在就是表里session_time,所以这里不需要传递参数的。为了清理会话中的旧数据,PHP 会不时的调用垃圾收集回调函数。 调用周期由 session.gc_probability 和 session.gc_pisor 参数控制。此回调函数操作成功返回 TRUE,反之返回 FALSE。

至此六个函数已经介绍完了,但是其中有许多需要说明的:

1、在open函数中本来是要传递save__path,目的是用来在这个路径下找到与session_name相对应的文件,然后通过read()函数来读取其中的数据,然后通过反序列化处理器将取到的字符串反序列化,在通过php自动填充各个$_session超全局变量。或者write函数来将序列化的数据存入这个路径下的文件。那么这里面的路径在非默认机制下难道就不需要吗,答案是肯定的*_*。当在非默认机制下,调试输出session_save_path,其结果为空值;而且如果未设置存储的路径,那被填充的$_session变量也只能在当前页面使用,而不能在别的页面使用,可以这样测试:在另一个页面利用session_start()函数打开会话,然后输出session_id和var_dump($_session),得到的是上一次浏览时服务器给客户端的session_id,但是$_session输出的是空数组(当然我这里只是大概的说一下我在验证时的过程)。其实我想说的就是我们在自定义会话存储机制的时候,是不需要自定义路径的,不然为什么还要存入数据库呢?    

那么怎么在其他页面也能读取到$_session[]里面的值呢?

 引入这个函数,即将六个 回调函数和session_set_save_handler放入一个文件里,然后在session_start()前用include()引入!

2、那他们的执行顺序是怎样呢?有点晕吧,来总结一下:首先session_start()函数打开session操作句柄,然后read函数读取数据,当脚本执行结束的时候执行write函数然后是close函数若有session_destroy()则执行完。

3、上面我提到过PHP 会在输出流写入完毕并且关闭之后才调用 write 回调函数,这个可把我玩坏啦,小编在上面可绕了不久呀,不然我也不会在write函数里调试那么久了!不过我也因此了解了register_shutdown_function这个函数,下面附上这个函数的特点吧:register_shutdown_function()是指在执行完所有PHP语句后再调用函数,不要理解成客户端关闭流浏览器页面时调用函数。

可以这样理解调用条件:
1、当页面被用户强制停止时
2、当程序代码运行超时时
3、当PHP代码执行完成时,代码执行存在异常和错误、警告

好了以上该说的都说完了,附上代码吧:

index.php用户登录界面

<?php


include("session_set_save_handler.php");//引入自定义的会话存储机制


if(isset($_GET["login"])){//判断login是否有值,若有值则要进行注销,


session_start();//只要需要 用到$_session变量的地方,就需要开启回调函数open


session_destroy();//这里就是上文提到的 小细节了,当有session_destroy的时候,它是先于read回调函数执行的


}else{


session_start();


if(isset($_SESSION["user"])){//判断此值是否有定义,若有定义则说明 存入的session还未到期,则直接转到主内容


echo "<script>alert(&#39;您不久前刚来过&#39;);window.location.href=&#39;main.php&#39;;</script>";

}

}

?>

<html>

<meta charset="utf-8">

<body>

<form action="index_ok.php" method="post">

账    户:<input type="text" name="user"><br>

密    码:<input type="text" name="pwd">

<input type="submit" name="sub">

</form>

</body>

</html>

index_ok.php表单提交处理文件

<?php


include("session_set_save_handler.php");


session_start();


if($_POST["sub"]){//$_post["sub"]它若有值就是 提交查询


echo $_POST["sub"];


if($_POST["user"]!=""&&$_POST["pwd"]!=""){


$_SESSION["user"]=$_POST["user"];


$_SESSION["pwd"]=$_POST["pwd"];//这里自定义的会话管理机制将会调用回调函数write,将已由序列化处理器处理好的(由$_session[]变量形成)字符串写入数据库


echo "<script>alert(&#39;登录成功!&#39;);window.location.href=&#39;main.php&#39;;</script>";

}

}


?>

main.php主内容页

<?php


include("session_set_save_handler.php");


session_start();


if(isset($_SESSION["user"])){


echo "欢迎".$_SESSION["user"];

echo "<a href=&#39;index.php?login=0&#39;>注销</a>";


}else{


echo "您还没登录,请先登录!";

echo "<a href=&#39;index.php&#39;>登录</a>";

}


?>

session_set_save_handler.php自定义session存储机制函数文件

<?php

//打开会话

function open(){


global $con;//使用全局变量


$con=mysqli_connect("localhost","root","123456","mysql")or die("数据库连接失败!");


mysqli_query($con,"set names utf8");


return(true);


}

//关闭数据库

function close(){


global $con;


mysqli_close($con);


return(true);


}

//读取session_data

function read($key){


global $con;

$time=time();

//不读取已过期的session

$sql="select session_data from t_session where session_key=&#39;$key&#39; and session_time>$time";


$result=mysqli_query($con,$sql)or die("查询失败!");


if (!$result) {//用来检查出现再数据库部分的错误,很有用


printf("Error: %s\n", mysqli_error($con));//%s表示的是字符串,这是c里面的


exit();

}


$row=mysqli_fetch_array($result);//or die()会终止后面的程序!


if($row!=false){


return($row["session_data"]);


}else{


return "";//再次强调如果空值 ,则一定 要返回”“而不是false


}


}

//存储session

function write($key,$data){



global $con;




$over_time=time()+60;//注意time()为时间戳,在mysql中的数据类型不可用用date,datetime,timestamp来存储


$sql="select session_data from t_session where session_key=&#39;$key&#39;";


$re=mysqli_query($con,$sql);


$result=mysqli_fetch_array($re);


//若$result为false,即结果 为空,说明数据库中未存有相应的session_id,那么就插入,如果不为空,那即使还有未过期的session_id,这是应更新


if($result==false){




$sql="insert into t_session(session_key,session_data,session_time ) values(&#39;$key&#39;,&#39;$data&#39;,$over_time)";//字符串的时候要加单引号,数字的时候是不用加的


$result=mysqli_query($con,$sql);


if (!$result) {//用来检查出现再数据库部分的错误,很有用

printf("Error: %s\n", mysqli_error($con));//%s表示的是字符串,这是c里面的

exit();

}




}else{




$sql="update t_session set session_key=&#39;$key&#39;,session_data=&#39;$data&#39;,session_time=$over_time where session_key=&#39;$key&#39;";


$result=mysqli_query($con,$sql);

}




return($result);


}

清楚相应的session数据

function destroy($key){




global $con;


$sql="delete from t_session where session_key=&#39;$key&#39;";


$result=mysqli_query($con,$sql);


return($result);


}


//执行垃圾回收


function overdue($expire_time){//这个参数是自动传进去的,就是session.gc_maxlifetime最大有效时间,例如1440s;


global $con;


$time=time();


$sql="delete from t_session where session_time<$time";


$result=mysqli_query($sql);


return($result);


}


session_set_save_handler(&#39;open&#39;,&#39;close&#39;,&#39;read&#39;,&#39;write&#39;,&#39;destroy&#39;,&#39;overdue&#39;);


?>

相关文章推荐:

php使用PHPMailer如何发送邮件(附代码)

PHP中常用的一些功能总结(归纳)

以上是PHP中如何將session存入資料庫並使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何計算PHP多維數組的元素總數?如何計算PHP多維數組的元素總數?May 15, 2025 pm 09:00 PM

計算PHP多維數組的元素總數可以使用遞歸或迭代方法。 1.遞歸方法通過遍歷數組並遞歸處理嵌套數組來計數。 2.迭代方法使用棧來模擬遞歸,避免深度問題。 3.array_walk_recursive函數也能實現,但需手動計數。

PHP中do-while循環有什麼特點?PHP中do-while循環有什麼特點?May 15, 2025 pm 08:57 PM

在PHP中,do-while循環的特點是保證循環體至少執行一次,然後再根據條件決定是否繼續循環。 1)它在條件檢查之前執行循環體,適合需要確保操作至少執行一次的場景,如用戶輸入驗證和菜單系統。 2)然而,do-while循環的語法可能導致新手困惑,且可能增加不必要的性能開銷。

PHP中如何哈希字符串?PHP中如何哈希字符串?May 15, 2025 pm 08:54 PM

在PHP中高效地哈希字符串可以使用以下方法:1.使用md5函數進行快速哈希,但不適合密碼存儲。 2.使用sha256函數提高安全性。 3.使用password_hash函數處理密碼,提供最高安全性和便捷性。

PHP中如何實現數組滑動窗口?PHP中如何實現數組滑動窗口?May 15, 2025 pm 08:51 PM

在PHP中實現數組滑動窗口可以通過函數slidingWindow和slidingWindowAverage來完成。 1.使用slidingWindow函數可以將數組分割成固定大小的子數組。 2.使用slidingWindowAverage函數可以在每個窗口內計算平均值。 3.對於實時數據流,可以使用ReactPHP進行異步處理和異常值檢測。

PHP中__clone方法怎麼用?PHP中__clone方法怎麼用?May 15, 2025 pm 08:48 PM

PHP中的__clone方法用於在對象克隆時進行自定義操作。使用clone關鍵字克隆對象時,如果對像有__clone方法,會自動調用該方法,允許在克隆過程中進行定制化處理,如重置引用類型屬性以確保克隆對象的獨立性。

PHP中goto語句如何使用?PHP中goto語句如何使用?May 15, 2025 pm 08:45 PM

在PHP中,goto語句用於無條件跳轉到程序中的特定標籤。 1)它可以簡化複雜嵌套循環或條件語句的處理,但2)使用goto可能導致代碼難以理解和維護,3)建議優先使用結構化控制語句。整體而言,goto應謹慎使用,並遵循最佳實踐以確保代碼的可讀性和可維護性。

PHP中如何實現數據統計?PHP中如何實現數據統計?May 15, 2025 pm 08:42 PM

在PHP中,數據統計可以通過使用內置函數、自定義函數和第三方庫來實現。 1)使用內置函數如array_sum()和count()進行基本統計。 2)編寫自定義函數計算中位數等複雜統計。 3)利用PHP-ML庫進行高級統計分析。通過這些方法,可以高效地進行數據統計。

PHP中如何使用匿名函數?PHP中如何使用匿名函數?May 15, 2025 pm 08:39 PM

是的,PHP中的匿名函數是指沒有名字的函數。它們可以作為參數傳遞給其他函數,並作為函數的返回值,使代碼更加靈活和高效。使用匿名函數時需要注意作用域和性能問題。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具