深度实现session【包括session入库、session机制和session和cookie的使用方法,完善会话机制(在分布式机器中也能使用)】、无限分类的实现...
1.session的注意點(diǎn):
@session_start();//這個(gè)配置需要注意,session開啟中會(huì)有影響,所以使用錯(cuò)誤抑制符進(jìn)行限制【并且使用php.ini對session進(jìn)行自動(dòng)開啟】
session_start()前的輸出問題:
【session信息本身會(huì)增加到http頭信息,也就是http主體不能在頭前】
對php.ini中的輸出緩存進(jìn)行配置,out_buffer的配置【注意:開啟之后能夠保證輸出內(nèi)容在腳本中緩存】
【注意】
(1)腳本中session變量的鍵只能是字符串類型的【$_SESSION[10]這樣是錯(cuò)誤的,因?yàn)閟ession本身是需要進(jìn)行序列化】
(2)如果不聲明session_start()的話,$_SESSION變量就相當(dāng)于一個(gè)普通數(shù)組進(jìn)行操作【與session文件不進(jìn)行交互】
(3)不能unset來刪除$_SESSION來刪除所有session變量,而是通過將session設(shè)置為空來實(shí)現(xiàn)【unset只是將讀取出來的session數(shù)據(jù)銷毀,對session文件的數(shù)據(jù)無影響】
(4)刪除session文件【session_destory()實(shí)現(xiàn)對session文件的銷毀】【只刪除文件,不會(huì)對$_SESSION變量進(jìn)行處理】【一旦執(zhí)行session_destory操作,不會(huì)再執(zhí)行session寫操作,即使有session變量存在】
【注意完全刪除一個(gè)session:將與當(dāng)前session相關(guān)的數(shù)據(jù)完全銷毀之后,再刪除文件以及sessionID(在cookie中)的刪除】
【完全刪除session需要考慮的就是會(huì)話機(jī)制本身】
?
2.session的存儲(chǔ)處理
session.save_path進(jìn)行session文件的路徑修改
當(dāng)請求變多之后,session文件會(huì)變多,此時(shí)如何管理?
通過session.save_path進(jìn)行多級子目錄進(jìn)行管理【根據(jù)sessionID進(jìn)行分級管理】
sessionID的形成算法:hash【session.hash_bits_per_character = 5(這里表示第一級子目錄總共有2^5=32種分別為0-9,a-v)】
session文件的管理還是有問題:
文件量大,管理不方便
難共享【分布式的服務(wù)器的管理問題】
解決方案:將session數(shù)據(jù)放入數(shù)據(jù)庫服務(wù)器中進(jìn)行保存管理【將session入庫的處理】
3.session入庫
將session機(jī)制中讀文件和寫文件的機(jī)制,通過數(shù)據(jù)庫進(jìn)行介入管理。
【設(shè)置一個(gè)公共類進(jìn)行session入口的所有方法】
session_set_save_handle();//函數(shù)的使用,結(jié)合session的機(jī)制,進(jìn)行調(diào)用指定的方法
這個(gè)方法的使用,按照一定的順序進(jìn)行規(guī)范調(diào)用。
//關(guān)于session的文件創(chuàng)建(入庫不需要文件創(chuàng)建)和需要session讀寫等操作的機(jī)制還是session自身的機(jī)制【所以需要使用指定的session函數(shù):session_set_save_handle以及內(nèi)部的方法要具體實(shí)現(xiàn)】
【相當(dāng)于實(shí)現(xiàn)了一個(gè)注冊函數(shù),結(jié)合php內(nèi)部機(jī)制實(shí)現(xiàn)session的入庫操作(只是入庫將session機(jī)制本身需要?jiǎng)?chuàng)建的文件,改為對數(shù)據(jù)庫的操作)】
session入庫本身就是講原本要寫入文本中的數(shù)據(jù),寫入數(shù)據(jù)庫中【從而解決了session文本太過多,難以管理】
設(shè)計(jì)存入數(shù)據(jù)庫表內(nèi)的數(shù)據(jù)的格式【數(shù)據(jù)類型,因?yàn)閟essionID本身就是唯一或者主鍵形式的】
【注意】
【對session的入庫操作需要單獨(dú)進(jìn)行封裝,不過也不需要感覺太難,就是不使用session對文件處理的機(jī)制,對文件的寫文件等機(jī)制進(jìn)行session_set_save_handle重寫(保存session基本機(jī)制(對session處理的時(shí)機(jī)不變),只有讀寫針對的情景不一樣),將session對文件的處理移到數(shù)據(jù)庫讀寫來提升性能】
session_set_save_handle:執(zhí)行的順序需要注意
對open和close的方法進(jìn)行初始化和析構(gòu)處理
?
4.session的垃圾回收
session里的gc函數(shù)實(shí)現(xiàn)session的垃圾回收【因?yàn)閟ession的垃圾回收比腳本要特殊,腳本結(jié)束,php垃圾回收,但是session需要先寫數(shù)據(jù),然后再釋放】
如果session入庫之后,由于session中保存的沒有用的sessionID也需要進(jìn)行回收,這也屬于session的垃圾回收
【如何判斷是否失效的原則】
cookie中如果sessionID失效,也會(huì)導(dǎo)致session內(nèi)的ID失效(cookie中保存sessionID被刷新,那么服務(wù)器上保存的id再也找不到對應(yīng)的id,此時(shí)服務(wù)器上的id便后失效)【失效sessionID其實(shí)出現(xiàn)的次數(shù)非常多】
php處理sessionID是否是垃圾的原則:php認(rèn)為某條ID多長時(shí)間不使用,來判斷是否是垃圾【垃圾回收基于時(shí)間:默認(rèn)1440s,通過php配置進(jìn)行修改】
session.gc相關(guān)的配置都是關(guān)于session的垃圾處理【每當(dāng)開啟session_start()都會(huì)有概率進(jìn)行垃圾回收】
【session_start()會(huì)進(jìn)行垃圾回收的查找,但是只是有幾率進(jìn)行g(shù)c垃圾回收,這也是為了提升性能。因?yàn)椴⒉皇?#xff0c;每次session_start都會(huì)實(shí)現(xiàn)一次gc垃圾處理】
【用mysql入庫的數(shù)據(jù)內(nèi)進(jìn)行時(shí)間來判斷垃圾回收的處理機(jī)制:這里的處理機(jī)制更加容易控制】
【session_set_save_handle:執(zhí)行的順序有合理性,刪除在讀取之后,能夠保證即使過期還是可以正常讀取(有可能)】
【重點(diǎn)!!!】
【使用入庫之后處理session的順序需要自己對session處理的機(jī)制】
(1)session_start()。首先進(jìn)行open【操作初始化】
(2)執(zhí)行read,進(jìn)行讀取
(3)有可能執(zhí)行g(shù)c垃圾回收
(4)在腳本執(zhí)行過程中時(shí),會(huì)針對session變量和有可能執(zhí)行session_destory
(5)腳本執(zhí)行完成,如果沒有執(zhí)行session_destory,那么就會(huì)執(zhí)行一個(gè)write操作
(6)腳本執(zhí)行完成后,進(jìn)行close操作
以上就是把session在腳本中執(zhí)行的順序
5.session中常見的問題
(1)session和cookie的區(qū)別和聯(lián)系
存儲(chǔ)位置,安全級別。二者的聯(lián)系也是sessionID
(2)session數(shù)據(jù)的有效期
瀏覽器關(guān)閉。
請求中的cookie保存的sessionID失效【默認(rèn)中的sessionID的cookie變量是一個(gè)臨時(shí)變量】
【這一點(diǎn)要注意,如果沒有將cookie中的sessionID進(jìn)行持久化,那么重新開啟一個(gè)瀏覽器,就相當(dāng)于重新獲得一個(gè)sessionID】
(3)由問題2帶來一個(gè)問題:如何持久化session。【同一個(gè)用戶的再次開啟同一個(gè)瀏覽器的話,能夠獲得同一個(gè)sessionID】
延長cookie變量的有效期【持久化sessionID的cookie變量】
至于session本身的保留跟session的持久化只是一部分
【只有cookie中關(guān)于sessionID做到持久化,session中保留的數(shù)據(jù)才有意義】
【不過服務(wù)器端對session保存的時(shí)間的長短也要和cookie中設(shè)置的sessionID的時(shí)間要統(tǒng)一】
session_set_cookie_params();//這個(gè)函數(shù)的使用
setcookie();//兩個(gè)函數(shù)都正常
(4)cookie禁用,session并不能用【url傳遞sessionID并不安全】
session.use_only_cookie:進(jìn)行session使用的配置
以上就是session的所有問題
?
6.設(shè)計(jì)列表:分類管理【重點(diǎn)】
無限分類【一級一級的分類下去:用于頭部或者對層級深度的不同進(jìn)行一級級展示】
樹狀列表【各級節(jié)點(diǎn):節(jié)點(diǎn)關(guān)系由數(shù)據(jù)表進(jìn)行關(guān)聯(lián)】
【n個(gè)節(jié)點(diǎn)(數(shù)據(jù)),n-1條邊(數(shù)據(jù)關(guān)系:通過一個(gè)字段來實(shí)現(xiàn)關(guān)聯(lián))】
實(shí)現(xiàn)無限分類
【重點(diǎn)】
如何將關(guān)聯(lián)的數(shù)據(jù)進(jìn)行聯(lián)系【數(shù)據(jù)庫實(shí)現(xiàn)上下級的關(guān)聯(lián)創(chuàng)建!!!】
【sql語句的查找是關(guān)鍵:sql將該節(jié)點(diǎn)上的值取出來和任何節(jié)點(diǎn)中判斷父節(jié)點(diǎn)的值,將結(jié)果進(jìn)行返回即可實(shí)現(xiàn)】
在插入數(shù)據(jù)時(shí)的配置也需要對類id和關(guān)聯(lián)id進(jìn)行對應(yīng)添加,這一點(diǎn)也是創(chuàng)建分類時(shí)的關(guān)鍵
【重點(diǎn)】
利用遞歸實(shí)現(xiàn)無限分類
【一次性獲取所有的數(shù)據(jù),將數(shù)據(jù)進(jìn)行遞歸查找】【節(jié)省數(shù)據(jù)庫開銷】
這一點(diǎn)思路要注意【雖然表示sql語句中進(jìn)行條件判斷的思路比較容易整理,但是通過這樣的一次性操作,然后對數(shù)組進(jìn)行分組之后進(jìn)行無線分類顯示能夠?qū)崿F(xiàn)功能】
【只要有這個(gè)對數(shù)組操作的思路即可實(shí)現(xiàn)遞歸,遞歸的一級級的判斷依據(jù)就是父id是否等于子數(shù)據(jù)中的關(guān)聯(lián)id,來進(jìn)行遞歸】
【遞歸點(diǎn)和遞歸出口時(shí)遞歸需要注意的重點(diǎn),而這個(gè)無線分類的遞歸其實(shí)更加簡單,只要針對條件進(jìn)行遞歸即可,不需要有遞歸出口】
【遞歸中需要共享所有遞歸的結(jié)果放在一個(gè)容器中,所以需要使用靜態(tài)變量來做數(shù)組容器】
例子:
<?php
//一:
mysql_connect('127.0.0.1:3306', 'root', '123456');
$sql = "select * from itcast_shop.it_category where 1 order by sort_order";
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)) {
$list[] = $row;
}
echo '<pre>';
//var_dump($list);
//二,遞歸查找
/**
*
* @param $arr array 當(dāng)前所有的可能分類,在該數(shù)組內(nèi)查找子分類
* @param $p_id int 當(dāng)前查找的父ID
*
* @param $deep int 當(dāng)前遞歸調(diào)用的深度
*
* @return array 排序好的數(shù)組列表!
*/
function getTree($arr, $p_id, $deep=0) {
//利用一個(gè)靜態(tài)局部變量將所有依次找到的元素,都保存
static $tree = array();
//遍歷所有的可能分類,找到parent_id==$p_id
foreach($arr as $row) {
//判斷是否為子分類
if($row['parent_id'] == $p_id) {
//是子分類
//記錄當(dāng)前所找到
$row['deep'] = $deep;
$tree[] = $row;
//利用當(dāng)前查找的分類,找其子分類
//遞歸調(diào)用
getTree($arr, $row['cat_id'], $deep+1);
}
}
return $tree;
}
$tree = getTree($list, 0);
//var_dump($tree);
foreach($tree as $row) {
echo $row['deep'];
echo str_repeat(' ', $row['deep']);//將一個(gè)字符串重復(fù)
echo $row['cat_name'];
echo '<br>';
}
?
以上實(shí)現(xiàn)了遞歸調(diào)用的方法【重點(diǎn)遞歸的實(shí)現(xiàn)和遞歸的容器需要考慮靜態(tài)變量來實(shí)現(xiàn)】
?
轉(zhuǎn)載于:https://www.cnblogs.com/shuoshuren/p/4231857.html
總結(jié)
以上是生活随笔為你收集整理的深度实现session【包括session入库、session机制和session和cookie的使用方法,完善会话机制(在分布式机器中也能使用)】、无限分类的实现...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 调用cmd不显示黑框的方法
- 下一篇: SQL优化的若干原则