深度實現session【包括session入庫、session機制和session和cookie的使用方法,完善會話機制(在分佈式機器中也能使用)】、無限分類的實現

1.session的注意點:
@session_start();//這個配置須要注意,session開啓中會有影響,因此使用錯誤抑制符進行限制【而且使用php.ini對session進行自動開啓】php

session_start()前的輸出問題:
【session信息自己會增長到http頭信息,也就是http主體不能在頭前】
對php.ini中的輸出緩存進行配置,out_buffer的配置【注意:開啓以後可以保證輸出內容在腳本中緩存】mysql

【注意】
(1)腳本中session變量的鍵只能是字符串類型的【$_SESSION[10]這樣是錯誤的,由於session自己是須要進行序列化】
(2)若是不聲明session_start()的話,$_SESSION變量就至關於一個普通數組進行操做【與session文件不進行交互】
(3)不能unset來刪除$_SESSION來刪除全部session變量,而是經過將session設置爲空來實現【unset只是將讀取出來的session數據銷燬,對session文件的數據無影響】
(4)刪除session文件【session_destory()實現對session文件的銷燬】【只刪除文件,不會對$_SESSION變量進行處理】【一旦執行session_destory操做,不會再執行session寫操做,即便有session變量存在】
【注意徹底刪除一個session:將與當前session相關的數據徹底銷燬以後,再刪除文件以及sessionID(在cookie中)的刪除】
【徹底刪除session須要考慮的就是會話機制自己】算法

 

2.session的存儲處理
session.save_path進行session文件的路徑修改sql

當請求變多以後,session文件會變多,此時如何管理?
經過session.save_path進行多級子目錄進行管理【根據sessionID進行分級管理】數據庫

sessionID的造成算法:hash【session.hash_bits_per_character = 5(這裏表示第一級子目錄總共有2^5=32種分別爲0-9,a-v)】數組

session文件的管理仍是有問題:
文件量大,管理不方便
難共享【分佈式的服務器的管理問題】瀏覽器

解決方案:將session數據放入數據庫服務器中進行保存管理【將session入庫的處理】緩存


3.session入庫
將session機制中讀文件和寫文件的機制,經過數據庫進行介入管理。
【設置一個公共類進行session入口的全部方法】安全

session_set_save_handle();//函數的使用,結合session的機制,進行調用指定的方法
這個方法的使用,按照必定的順序進行規範調用。
//關於session的文件建立(入庫不須要文件建立)和須要session讀寫等操做的機制仍是session自身的機制【因此須要使用指定的session函數:session_set_save_handle以及內部的方法要具體實現】
【至關於實現了一個註冊函數,結合php內部機制實現session的入庫操做(只是入庫將session機制自己須要建立的文件,改成對數據庫的操做)】
session入庫自己就是講本來要寫入文本中的數據,寫入數據庫中【從而解決了session文本太過多,難以管理】服務器


設計存入數據庫表內的數據的格式【數據類型,由於sessionID自己就是惟一或者主鍵形式的】


【注意】
【對session的入庫操做須要單獨進行封裝,不過也不須要感受太難,就是不使用session對文件處理的機制,對文件的寫文件等機制進行session_set_save_handle重寫(保存session基本機制(對session處理的時機不變),只有讀寫針對的情景不同),將session對文件的處理移到數據庫讀寫來提高性能】
session_set_save_handle:執行的順序須要注意
對open和close的方法進行初始化和析構處理

 

4.session的垃圾回收
session裏的gc函數實現session的垃圾回收【由於session的垃圾回收比腳本要特殊,腳本結束,php垃圾回收,可是session須要先寫數據,而後再釋放】

若是session入庫以後,因爲session中保存的沒有用的sessionID也須要進行回收,這也屬於session的垃圾回收
【如何判斷是否失效的原則】
cookie中若是sessionID失效,也會致使session內的ID失效(cookie中保存sessionID被刷新,那麼服務器上保存的id再也找不到對應的id,此時服務器上的id便後失效)【失效sessionID其實出現的次數很是多】
php處理sessionID是不是垃圾的原則:php認爲某條ID多長時間不使用,來判斷是不是垃圾【垃圾回收基於時間:默認1440s,經過php配置進行修改】


session.gc相關的配置都是關於session的垃圾處理【每當開啓session_start()都會有機率進行垃圾回收】
【session_start()會進行垃圾回收的查找,可是隻是有概率進行gc垃圾回收,這也是爲了提高性能。由於並非,每次session_start都會實現一次gc垃圾處理】
【用mysql入庫的數據內進行時間來判斷垃圾回收的處理機制:這裏的處理機制更加容易控制】


【session_set_save_handle:執行的順序有合理性,刪除在讀取以後,可以保證即便過時仍是能夠正常讀取(有可能)】

【重點!!!】
【使用入庫以後處理session的順序須要本身對session處理的機制】
(1)session_start()。首先進行open【操做初始化】
(2)執行read,進行讀取
(3)有可能執行gc垃圾回收
(4)在腳本執行過程當中時,會針對session變量和有可能執行session_destory
(5)腳本執行完成,若是沒有執行session_destory,那麼就會執行一個write操做
(6)腳本執行完成後,進行close操做

以上就是把session在腳本中執行的順序


5.session中常見的問題
(1)session和cookie的區別和聯繫
存儲位置,安全級別。兩者的聯繫也是sessionID
(2)session數據的有效期
瀏覽器關閉。
請求中的cookie保存的sessionID失效【默認中的sessionID的cookie變量是一個臨時變量】
【這一點要注意,若是沒有將cookie中的sessionID進行持久化,那麼從新開啓一個瀏覽器,就至關於從新得到一個sessionID】
(3)由問題2帶來一個問題:如何持久化session。【同一個用戶的再次開啓同一個瀏覽器的話,可以得到同一個sessionID】
延長cookie變量的有效期【持久化sessionID的cookie變量】
至於session自己的保留跟session的持久化只是一部分
【只有cookie中關於sessionID作到持久化,session中保留的數據纔有意義】
【不過服務器端對session保存的時間的長短也要和cookie中設置的sessionID的時間要統一】


session_set_cookie_params();//這個函數的使用
setcookie();//兩個函數都正常


(4)cookie禁用,session並不能用【url傳遞sessionID並不安全】
session.use_only_cookie:進行session使用的配置


以上就是session的全部問題

 

6.設計列表:分類管理【重點】
無限分類【一級一級的分類下去:用於頭部或者對層級深度的不一樣進行一級級展現】
樹狀列表【各級節點:節點關係由數據表進行關聯】
【n個節點(數據),n-1條邊(數據關係:經過一個字段來實現關聯)】
實現無限分類

【重點】
如何將關聯的數據進行聯繫【數據庫實現上下級的關聯建立!!!】
【sql語句的查找是關鍵:sql將該節點上的值取出來和任何節點中判斷父節點的值,將結果進行返回便可實現】

在插入數據時的配置也須要對類id和關聯id進行對應添加,這一點也是建立分類時的關鍵


【重點】
利用遞歸實現無限分類
【一次性獲取全部的數據,將數據進行遞歸查找】【節省數據庫開銷】
這一點思路要注意【雖然表示sql語句中進行條件判斷的思路比較容易整理,可是經過這樣的一次性操做,而後對數組進行分組以後進行無線分類顯示可以實現功能】
【只要有這個對數組操做的思路便可實現遞歸,遞歸的一級級的判斷依據就是父id是否等於子數據中的關聯id,來進行遞歸】
【遞歸點和遞歸出口時遞歸須要注意的重點,而這個無線分類的遞歸其實更加簡單,只要針對條件進行遞歸便可,不須要有遞歸出口】
【遞歸中須要共享全部遞歸的結果放在一個容器中,因此須要使用靜態變量來作數組容器】


例子:
<?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 當前全部的可能分類,在該數組內查找子分類
* @param $p_id int 當前查找的父ID
*
* @param $deep int 當前遞歸調用的深度
*
* @return array 排序好的數組列表!
*/
function getTree($arr, $p_id, $deep=0) {
//利用一個靜態局部變量將全部依次找到的元素,都保存
static $tree = array();
//遍歷全部的可能分類,找到parent_id==$p_id
foreach($arr as $row) {
//判斷是否爲子分類
if($row['parent_id'] == $p_id) {
//是子分類
//記錄當前所找到
$row['deep'] = $deep;
$tree[] = $row;
//利用當前查找的分類,找其子分類
//遞歸調用
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('&nbsp;&nbsp;', $row['deep']);//將一個字符串重複
echo $row['cat_name'];
echo '<br>';
}

 

以上實現了遞歸調用的方法【重點遞歸的實現和遞歸的容器須要考慮靜態變量來實現】

相關文章
相關標籤/搜索