新聞中心
在web開發(fā)中,會(huì)話(Session)是一種非常重要的機(jī)制。它允許服務(wù)器在多個(gè)頁(yè)面之間存儲(chǔ)用戶的數(shù)據(jù),以便用戶可以保持已登錄狀態(tài)并在操作過(guò)程中保持他們之前的輸入。PHP作為一種流行的服務(wù)器端語(yǔ)言,提供了強(qiáng)大且易于使用的會(huì)話支持功能。而將會(huì)話存儲(chǔ)到數(shù)據(jù)庫(kù)中,可以提高應(yīng)用程序的安全性和可伸縮性。在本文中,我們將介紹一種簡(jiǎn)單易行的方法來(lái)實(shí)現(xiàn)PHP會(huì)話存儲(chǔ)到數(shù)據(jù)庫(kù)中。

文縣網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),文縣網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為文縣上千家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的文縣做網(wǎng)站的公司定做!
之一步:配置會(huì)話存儲(chǔ)方式
PHP默認(rèn)使用文件系統(tǒng)來(lái)保存會(huì)話數(shù)據(jù)。我們需要修改PHP配置文件,將會(huì)話存儲(chǔ)方式由文件系統(tǒng)改為數(shù)據(jù)庫(kù)。打開php.ini文件,在[Session]部分添加以下配置:
“`
session.save_handler = user
session.serialize_handler = php
session.gc_probability = 1
“`
其中,`session.save_handler`配置項(xiàng)用于設(shè)置會(huì)話存儲(chǔ)的方式。我們將這個(gè)配置項(xiàng)的值設(shè)為`user`,表示使用自定義的會(huì)話存儲(chǔ)方式。`session.serialize_handler`配置項(xiàng)指定會(huì)話數(shù)據(jù)的序列化方式,這里我們?cè)O(shè)置為`php`,表示使用PHP的序列化方式。`session.gc_probability`表示垃圾回收的概率,我們將其設(shè)置為1,表示每次請(qǐng)求都進(jìn)行垃圾回收。
第二步:實(shí)現(xiàn)自定義的會(huì)話存儲(chǔ)方式
接下來(lái),我們需要實(shí)現(xiàn)自定義的會(huì)話存儲(chǔ)方式。在PHP中,我們可以通過(guò)自定義會(huì)話處理函數(shù)來(lái)實(shí)現(xiàn)這一點(diǎn)。打開一個(gè)新的PHP文件,我們可以實(shí)現(xiàn)一個(gè)會(huì)話處理函數(shù),例如:
“`
function db_open($save_path, $session_name)
{
//TODO: database connection
return true;
}
function db_close()
{
//TODO: database disconnection
return true;
}
function db_read($id)
{
//TODO: read from database
}
function db_write($id, $data)
{
//TODO: write to database
}
function db_destroy($id)
{
//TODO: delete from database
return true;
}
function db_gc($maxlifetime)
{
//TODO: delete expired sessions from database
return true;
}
session_set_save_handler(
‘db_open’, ‘db_close’, ‘db_read’,
‘db_write’, ‘db_destroy’, ‘db_gc’
);
“`
上面的代碼中,`db_open`函數(shù)用于連接數(shù)據(jù)庫(kù),`db_close`函數(shù)用于關(guān)閉數(shù)據(jù)庫(kù)連接,`db_read`函數(shù)用于從數(shù)據(jù)庫(kù)中讀取會(huì)話數(shù)據(jù),`db_write`函數(shù)用于將會(huì)話數(shù)據(jù)寫入數(shù)據(jù)庫(kù),`db_destroy`函數(shù)用于刪除會(huì)話數(shù)據(jù),`db_gc`函數(shù)用于清理過(guò)期的會(huì)話數(shù)據(jù)。最后一行使用`session_set_save_handler`函數(shù)將自定義的會(huì)話處理函數(shù)注冊(cè)為系統(tǒng)默認(rèn)的處理函數(shù)。
第三步:實(shí)現(xiàn)自定義的會(huì)話處理函數(shù)
上面的代碼中,我們將會(huì)話數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中?,F(xiàn)在我們需要實(shí)現(xiàn)`db_open`、`db_close`、`db_read`、`db_write`、`db_destroy`和`db_gc`函數(shù)。
`db_open`函數(shù)用于連接數(shù)據(jù)庫(kù),我們可以使用PHP提供的數(shù)據(jù)庫(kù)擴(kuò)展,例如PDO或mysqli來(lái)連接數(shù)據(jù)庫(kù)。這里我們使用PDO作為示例。
“`
function db_open($save_path, $session_name)
{
//TODO: database connection
$pdo = new PDO(‘mysql:host=localhost;dbname=test’, ‘root’, ‘password’);
return true;
}
“`
`db_close`函數(shù)用于關(guān)閉數(shù)據(jù)庫(kù)連接:
“`
function db_close()
{
//TODO: database disconnection
$pdo = null;
return true;
}
“`
`db_read`函數(shù)用于從數(shù)據(jù)庫(kù)中讀取會(huì)話數(shù)據(jù):
“`
function db_read($id)
{
//TODO: read from database
global $pdo;
$stmt = $pdo->prepare(“SELECT data FROM sessions WHERE id = ?”);
$stmt->execute([$id]);
$data = $stmt->fetchColumn();
return $data;
}
“`
`db_write`函數(shù)用于將會(huì)話數(shù)據(jù)寫入數(shù)據(jù)庫(kù):
“`
function db_write($id, $data)
{
//TODO: write to database
global $pdo;
$stmt = $pdo->prepare(“REPLACE INTO sessions (id, data) VALUES (?, ?)”);
$stmt->execute([$id, $data]);
return true;
}
“`
`db_destroy`函數(shù)用于刪除會(huì)話數(shù)據(jù):
“`
function db_destroy($id)
{
//TODO: delete from database
global $pdo;
$stmt = $pdo->prepare(“DELETE FROM sessions WHERE id = ?”);
$stmt->execute([$id]);
return true;
}
“`
`db_gc`函數(shù)用于清理過(guò)期的會(huì)話數(shù)據(jù):
“`
function db_gc($maxlifetime)
{
//TODO: delete expired sessions from database
global $pdo;
$stmt = $pdo->prepare(“DELETE FROM sessions WHERE expiry
$stmt->execute([time() – $maxlifetime]);
return true;
}
“`
現(xiàn)在,我們已經(jīng)完成了自定義的會(huì)話處理函數(shù)的實(shí)現(xiàn),可以開始使用了。
第四步:?jiǎn)?dòng)會(huì)話
在使用自定義的會(huì)話處理函數(shù)之前,我們需要調(diào)用`session_set_save_handler`函數(shù)注冊(cè)自定義的處理函數(shù)。我們可以將該代碼放在啟動(dòng)會(huì)話之前,例如:
“`
function session_handler()
{
require_once ‘session.php’;
}
session_set_save_handler(
‘db_open’, ‘db_close’, ‘db_read’,
‘db_write’, ‘db_destroy’, ‘db_gc’
);
session_start();
“`
在這段代碼中,我們調(diào)用了`require_once`函數(shù)來(lái)包含自定義的會(huì)話處理函數(shù)。然后再使用`session_set_save_handler`函數(shù)注冊(cè)自定義的處理函數(shù),并使用`session_start`函數(shù)啟動(dòng)會(huì)話。
第五步:測(cè)試會(huì)話
現(xiàn)在,我們已經(jīng)完成了將會(huì)話存儲(chǔ)到數(shù)據(jù)庫(kù)的整個(gè)過(guò)程,可以進(jìn)行測(cè)試了。我們可以創(chuàng)建一個(gè)測(cè)試腳本來(lái)測(cè)試會(huì)話是否正確地存儲(chǔ)到數(shù)據(jù)庫(kù)中。例如:
“`
session_start();
if (!isset($_SESSION[‘count’])) {
$_SESSION[‘count’] = 0;
} else {
$_SESSION[‘count’]++;
}
echo ‘Count: ‘ . $_SESSION[‘count’];
“`
上面的代碼中,我們使用`$_SESSION`超全局變量來(lái)存儲(chǔ)會(huì)話數(shù)據(jù),并使用`echo`語(yǔ)句輸出會(huì)話數(shù)據(jù)的值。我們可以在不同的瀏覽器或電腦中打開這個(gè)測(cè)試腳本,測(cè)試會(huì)話是否跨會(huì)話或跨瀏覽器保存。
我們已經(jīng)使用簡(jiǎn)單易行的方法將PHP會(huì)話存儲(chǔ)到數(shù)據(jù)庫(kù)中了。這種方法可以提高應(yīng)用程序的安全性和可伸縮性,同時(shí)還可以允許多個(gè)服務(wù)器之間共享會(huì)話數(shù)據(jù)。這對(duì)于大型web應(yīng)用程序來(lái)說(shuō)非常重要。
相關(guān)問(wèn)題拓展閱讀:
- 如何將PHP session信息緩存到memcached里面
如何將PHP session信息緩存到memcached里面
memcached 是一套分布式的快取系統(tǒng),當(dāng)初是Danga Interactive為了LiveJournal所發(fā)展的,但被許多軟件(如MediaWiki)所使用。這是一套開放源代碼軟件,以BSD license授權(quán)協(xié)議發(fā)布。
memcached 僅支持一些非常簡(jiǎn)單的命令 比如get(獲取某個(gè)鍵值) set(用來(lái)設(shè)定或保存一個(gè)緩存);
其本身是緩存服務(wù)器,但本身無(wú)法決定緩存任何數(shù)據(jù),其緩存機(jī)制依賴于服務(wù)端和客戶端兩者必不可少(存儲(chǔ)是由服務(wù)端進(jìn)行存儲(chǔ),但存儲(chǔ)什么是由客戶端進(jìn)行決定的)
因此客戶端要自己提供緩存的鍵名以及時(shí)長(zhǎng)、標(biāo)志位、整個(gè)數(shù)據(jù)大小等等
例如:只存儲(chǔ)hello 但只存儲(chǔ)60秒
set key 5 60 hello
并告知服務(wù)器端,這樣存儲(chǔ)過(guò)了60秒后,由服務(wù)端進(jìn)行清除數(shù)據(jù)
但是其工作機(jī)制非常獨(dú)特,其緩存功能是基于Lazy模型的:
只要空間未滿則不清理
那么問(wèn)題來(lái)了:如果空間過(guò)小,而需緩存的內(nèi)容過(guò)大的話,那么導(dǎo)致緩存抖動(dòng)非常嚴(yán)重,存完即清理其次再去緩存這樣會(huì)導(dǎo)致命中率下降,而毫無(wú)意義
有些時(shí)候,有些數(shù)據(jù)管理不善有可能導(dǎo)致緩存崩潰等
如果memcached崩潰僅導(dǎo)致業(yè)務(wù)層的影響,最多是速度降低 而不會(huì)導(dǎo)致數(shù)據(jù)層
memcached 如何實(shí)現(xiàn)緩存的
memcached 通過(guò)內(nèi)存進(jìn)行緩存數(shù)據(jù),但并不實(shí)現(xiàn)持久緩存
存數(shù)數(shù)據(jù)的下限:
最小為48字節(jié)
更大不能超過(guò)1MB
但存儲(chǔ)的數(shù)據(jù)大小有可能不一致,比如:
index.html10k
test.jpg34k
那memcached如何在內(nèi)存中管理緩存數(shù)據(jù)
假如我們分別存儲(chǔ)不同大小的數(shù)據(jù)以上為例
很顯然只要分配一個(gè)足夠大的空間就可以了,但是在內(nèi)存中去找對(duì)應(yīng)的數(shù)據(jù)我們必須要有對(duì)應(yīng)的緩存對(duì)象的邊界(起始存儲(chǔ)位地址和結(jié)束存儲(chǔ)位地址)將其當(dāng)做獨(dú)立的單位來(lái)管理
等其緩存失效了,空間會(huì)被騰出,時(shí)間久了可能會(huì)帶來(lái)碎片,因?yàn)榇鎯?chǔ)的都是非常小的數(shù)據(jù)單元,按理說(shuō)如果再想高速利用則會(huì)困難,所以在這種機(jī)制下memcached的存儲(chǔ)數(shù)據(jù) 查詢數(shù)據(jù)等操作都是非常緩慢的
由此,不??焖倩趦?nèi)存的申請(qǐng)、釋放反復(fù)操作,這種釋放本身也消耗大量的資源和時(shí)間
因此我們需要一種高效的機(jī)制來(lái)解決內(nèi)存的創(chuàng)建和釋放的問(wèn)題
對(duì)于memcached來(lái)講首要必須解決這類內(nèi)存碎片問(wèn)題,不然由于內(nèi)存的碎片導(dǎo)致進(jìn)程運(yùn)行的非常緩慢
在linux內(nèi)核中引入了兩種機(jī)制避免內(nèi)存碎片
1.buddy system 伙伴系統(tǒng)
為了實(shí)現(xiàn)整個(gè)內(nèi)存中以頁(yè)面方式管理內(nèi)存的時(shí)候有足夠大的連續(xù)內(nèi)存空間可用的,在物理內(nèi)存中,事實(shí)上內(nèi)存的管理和分配在內(nèi)核級(jí)別通常以頁(yè)面方式分配和使用的
通常是4k大小一個(gè)頁(yè)面,buddy就是為了將這些零碎的、空閑的合并成一個(gè)連續(xù)的大的內(nèi)存空間,這樣就避免了頁(yè)面之間產(chǎn)生碎片的,因此,其主要目的是為了避免內(nèi)存外碎片
2.slab allocator slab 分配器
實(shí)現(xiàn)將存儲(chǔ)小于頁(yè)面單位的非常小的數(shù)據(jù)內(nèi)存結(jié)構(gòu)的時(shí)候之前事先分配并隨時(shí)等待有需求的進(jìn)程或要存儲(chǔ)的對(duì)象使用,當(dāng)我們使用之后它也不會(huì)自動(dòng)消毀結(jié)構(gòu)而是隨時(shí)重復(fù)使用
避免內(nèi)存內(nèi)部碎片
最新版本的memcached使用的是增長(zhǎng)因子(growth factor)來(lái)明確定義起始點(diǎn)開始依次增長(zhǎng)
比如:
我們定義增長(zhǎng)因子為其2倍
我們存儲(chǔ)一個(gè)單位為48bytes,那么會(huì)分配其48*2 = 96bytes
如果增長(zhǎng)因子為1.1倍
那么48+48*1.1
php session 儲(chǔ)存到數(shù)據(jù)庫(kù)的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于php session 儲(chǔ)存到數(shù)據(jù)庫(kù),PHP會(huì)話存儲(chǔ)到數(shù)據(jù)庫(kù):簡(jiǎn)單易行的方法,如何將PHP session信息緩存到memcached里面的信息別忘了在本站進(jìn)行查找喔。
成都網(wǎng)站營(yíng)銷推廣找創(chuàng)新互聯(lián),全國(guó)分站站群網(wǎng)站搭建更好做SEO營(yíng)銷。
創(chuàng)新互聯(lián)(www.cdcxhl.com)四川成都IDC基礎(chǔ)服務(wù)商,價(jià)格厚道。提供成都服務(wù)器托管租用、綿陽(yáng)服務(wù)器租用托管、重慶服務(wù)器托管租用、貴陽(yáng)服務(wù)器機(jī)房服務(wù)器托管租用。
網(wǎng)頁(yè)名稱:PHP會(huì)話存儲(chǔ)到數(shù)據(jù)庫(kù):簡(jiǎn)單易行的方法 (php session 儲(chǔ)存到數(shù)據(jù)庫(kù))
瀏覽地址:http://m.fisionsoft.com.cn/article/dheiedh.html


咨詢
建站咨詢
