Session:在計算機中,尤其是在網路套用中,稱為“會話控制”。Session對象存儲特定用戶會話所需的屬性及配置信息。這樣,當用戶在應用程式的Web頁之間跳轉時,存儲在Session對象中的變數將不會丟失,而是在整個用戶會話中一直存在下去。當用戶請求來自應用程式的 Web頁時,如果該用戶還沒有會話,則Web伺服器將自動創建一個 Session對象。當會話過期或被放棄後,伺服器將終止該會話。Session 對象最常見的一個用法就是存儲用戶的首選項。例如,如果用戶指明不喜歡查看圖形,就可以將該信息存儲在Session對象中。有關使用Session 對象的詳細信息,請參閱“ASP應用程式”部分的“管理會話”。注意會話狀態僅在支持cookie的瀏覽器中保留。
基本介紹
- 中文名:時域
- 外文名:Session
- 所屬學科:計算機網路
- 套用學科:軟體 網路通信
- 屬性:用戶與互動系統通信的時間間隔
監控系統,實用精解,比較分析,
監控系統
基本定義
Session直接翻譯成中文比較困難,一般都譯成時域。在計算機專業術語中,Session是指一個終端用戶與互動系統進行通信的時間間隔,通常指從註冊進入系統到註銷退出系統之間所經過的時間。以及如果需要的話,可能還有一定的操作空間。
需要注意的是,一個Session的概念需要包括特定的客戶端,特定的伺服器端以及不中斷的操作時間。A用戶和C伺服器建立連線時所處的Session同B用戶和C伺服器建立連線時所處的Session是兩個不同的Session。
session的工作原理:
(1)當一個session第一次被啟用時,一個獨一的標識被存儲於本地的cookie中。
(2)首先使用session_start()函式,PHP從session倉庫中載入已經存儲的session變數。
(3)當執行PHP腳本時,通過使用session_register()函式註冊session變數。
(4)當PHP腳本執行結束時,未被銷毀的session變數會被自動保存在本地一定路徑下的session庫中,這個路徑可以通過php.ini檔案中的session.save_path指定,下次瀏覽網頁時可以載入使用。
解決方案
那什麼是Session的解決方案呢?用戶訪問一個網站時往往需要瀏覽許多網頁。Session的使用在不同的語言中的使用方法特點不盡相同。對於一個通過PHP構築的網站來說,用戶在訪問的過程中需要執行許多的PHP腳本。然而由於HTTP協定自身的特點,用戶每執行一個PHP腳本都需要和Web伺服器重新建立連線。
Session解決方案,就是要提供在PHP腳本中定義全局變數的方法,使得這個全局變數在同一個Session中對於所有的PHP腳本都有效。提到了,Session不是一個簡單的時間概念,一個Session中還包括了特定的用戶和伺服器。因此更詳細地講,在一個Session定義的全局變數的作用範圍,是指這個Session所對應的用戶所訪問的所有PHP。
例如A用戶通過Session定義了一個全局變數$user=“wind”中,而B用戶通過Session定義的全局變數$user=“jane”。那么在A用戶所訪問的PHP腳本中,$user的值就是wind。
使用方法
Session通常用於執行以下操作
存儲需要在整個用戶會話過程中保持其狀態的信息,例如登錄信息或用戶瀏覽Web應用程式時需要的其它信息。
存儲只需要在頁面重新載入過程中或按功能分組的一組頁之間保持其狀態的對象。
Session的作用就是它在Web伺服器上保持用戶的狀態信息供在任何時間從任何設備上的頁面進行訪問。因為瀏覽器不需要存儲任何這種信息,所以可以使用任何瀏覽器,即使是像Pad或手機這樣的瀏覽器設備。
持久性方法的限制
隨著越來越多用戶登錄,Session所需要的伺服器記憶體量也會不斷增加。
訪問Web應用程式的每個用戶都生成一個單獨的Session對象。每個Session對象的持續時間是用戶訪問的時間加上不活動的時間。
如果每個Session中保持許多對象,並且許多用戶同時使用Web應用程式(創建許多Session),則用於 Session持久性的伺服器記憶體量可能會很大,從而影響了可伸縮性。
實用精解
cookies和session,JSP基本語法,JSP使用JavaBean,整合Servlet和JSP(MVC),JSP表達式語言,JSP自製標籤,資料庫JDBC,網路安全,Servlet和JSP過濾器,Web套用事件監聽器,具體內容如下:
基本語法
1、對於值類型的變數,Session中保存的是值類型的拷貝
Session["__test0"] = 1;
int i = (int)Session["__test0"]+1;
int j = (int)Session["__test0"];
結果:i=2,j=1
2、對於引用類型的變數,Session中保存的是引用
CDACommon cda = new CDACommon();
Session["__test"] = cda.GetDataSet("select top 1 * from tb_customer");
DataSet ds = (DataSet)Session["__test"];
DataSet ds2 = (DataSet)Session["__test"];
ds.Tables[0].Rows[0][0]="9999";
結果:
ds.Tables[0].Rows[0][0]=="9999"
ds2.Tables[0].Rows[0][0]=="9999";
3、Session周期
新的瀏覽器視窗啟動後,開始一個新的Session,觸發Global的Session_Start的調用,從第一個瀏覽器視窗打開的瀏覽器視窗不啟動新的Session。Session過期後,執行頁面的提交也會觸發Session_Start,等於是新的一個Session。
4、調用Session
對於Web Service,每個方法的調用都會啟動一個Session,可以用下面的方法來使多個調用在同一個Session里 :
CWSSyscfg cwsCfg = new CWSSyscfg(); cwsCfg.CookieContainer = new System Net.CookieContainer(); CWSSyscfg是一個Web Service類,Web Service的給代理類設定CookieContainer屬性,只要多個代理的CookieContainer屬性是相同的值,則對這些Web Service的調用在同一個Session。可以用單例模式來實現。
5、Session數據有效期
只要頁面有提交活動,則Session的所有項都會保持,頁面在20分鐘(默認配置)內沒有任何提交活動時Session會失效。Session記憶體儲的多個數據項是整體失效的。
6、Session的保存
在Session中如果保存的是非序列化的類比如DataView,在用SQLServer保存Session的模式下,無法使用。查看一個類是否是序列化的方法是,需看是否用[Serializable]來標記了該類。
在PHP中
PHP session變數用於存儲關於用戶會話(session)的信息,或者更改用戶會話(session)的設定。Session變數存儲單一用戶的信息,並且對於應用程式中的所有頁面都是可用的。
PHP Session變數:
您在計算機上操作某個應用程式時,您打開它,做些更改,然後關閉它。這很像一次對話(Session)。計算機知道您是誰。它清楚您在何時打開和關閉應用程式。然而,在網際網路上問題出現了:由於HTTP地址無法保持狀態,Web伺服器並不知道您是誰以及您做了什麼。
PHP session解決了這個問題,它通過在伺服器上存儲用戶信息以便隨後使用(比如用戶名稱、購買商品等)。然而,會話信息是臨時的,在用戶離開網站後將被刪除。如果您需要永久存儲信息,可以把數據存儲在資料庫中。
Session的工作機制是:為每個訪客創建一個獨一的id (UID),並基於這個UID來存儲變數。UID存儲在cookie 中,或者通過URL進行傳導。
在JSP中
使用session功能,可以達到多個jsp程式從操作同一個java bean,那么這個java bean可以作為傳統意義上的"全局變數池".(在java中可以使用static靜態化一個變數和方法,使用singleton獨一化對象。)
在項目實踐中,Jsp程式中很多參數需要從資料庫中讀取,有的參數實際讀取一次就可以,如果設計成每個用戶每產生一個頁面都要讀取資料庫,很顯然,資料庫的負載很大,同時也浪費時間,雖然可能有資料庫連線池最佳化,但是儘量少使用資料庫是我們編程的原則。
JSP使用一個叫HttpSession的對象實現同樣的功能。HTTPSession是一個建立在cookies 和URL-rewriting上的高質量的界面。Session的信息保存在伺服器端,Session的id保存在客戶機的cookie中。事實上,在許多伺服器上,如果瀏覽器支持的話它們就使用cookies,但是如果不支持或廢除了的話就自動轉化為URL-rewriting,session自動為每個流程提供了方便地存儲信息的方法。
Httpsession具有如下API:
getId 此方法返回獨一的標識,這些標識為每個session而產生。當只有一個單一的值與一個session聯合時,或當日誌信息與先前的sessions有關時,它被當作鍵名用。
GetCreationTime 返回session被創建的時間。最小單位為千分之一秒。為得到一個對列印輸出很有用的值,可將此值傳給Date constructor 或者GregorianCalendar的方法setTimeInMillis.
GetLastAccessedTime 返回session最後被客戶傳送的時間。最小單位為千分之一秒。
GetMaxInactiveInterval 返回總時間(秒),負值表示session永遠不會逾時。
getAttribute 取一個session相聯繫的信息。(在jsp1.0中為 getValue)。
Integer item = (Integer) session.getAttribute("item") //檢索出session的值並轉化為整型。
setAttribute 提供一個關鍵字和一個值。會替換掉任何以前的值。(在jsp1.0中為putValue)。
session.setAttribute("ItemValue", itemName); // ItemValue 必須不是must簡單類型。
在套用中使用最多的是getAttribute和setAttribute。現以一個簡單的例子來說明session的套用,test1.jsp(信息寫入session),test2.jsp(從session讀出信息)。
test1.jsp
<HTML>
<HEAD>
<TITLE> Document </TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<%
session.setAttribute("str",new String(“this is test”));
%>
</BODY>
</HTML>
test2.jsp
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<%
String ls_str=null;
ls_str=(String)session.getAttribute("str");
out.println(“從session里取出的值為:”+ls_str);
%>
</BODY>
</HTML>
使用詳解
php中的Session與Cookie
在PHP開發中對比起Cookie,session是存儲在伺服器端的會話,相對安全,並且不像Cookie那樣有存儲長度限制,簡單介紹session的使用。
由於Session是以文本檔案形式存儲在伺服器端的,所以不怕客戶端修改Session內容。實際上在伺服器端的Session檔案,PHP自動修改session檔案的許可權,只保留了系統讀和寫許可權,而且不能通過ftp修改,所以安全得多。
當然使用session還有很多優點,比如控制容易,可以按照用戶自定義存儲等(存儲於資料庫)。
Php如何創建Session
開始介紹如何創建session。非常簡單,真的。
啟動session會話,並創建一個$admin變數:
// 啟動session
session_start();
// 聲明一個名為admin的變數,並賦空值。
$_session["admin"] = null;
>
如果你使用了Session,或者該PHP檔案要調用Session變數,那么就必須在調用Session之前啟動它,使用 session_start()函式。其它都不需要你設定了,PHP自動完成session檔案的創建。
執行完這個程式後,可以到系統臨時資料夾找到這個 session 檔案,一般檔案名稱形如:sess_4c83638b3b0dbf65583181c2f89168ec,後面是32位編碼後的隨機字元串。用編輯器打開它,看一下它的內容:
admin|N;
Session是什麼呢? 簡單來說就是伺服器給客戶端的一個編號。當一台WWW伺服器運行時,可能有若干個用戶瀏覽正在運行這台伺服器上的網站。當每個用戶首次與這台WWW伺服器建立連線時,他就與這個伺服器建立了一個Session,同時伺服器會自動為其分配一個SessionID,用以標識這個用戶的身份。這個SessionID是由WWW伺服器隨機產生的一個由24個字元組成的字元串。
這個的SessionID是有很大的實際意義的。當一個用戶提交了表單時,瀏覽器會將用戶的SessionID自動附加在HTTP頭信息中,(這是瀏覽器的自動功能,用戶不會察覺到),當伺服器處理完這個表單後,將結果返回給SessionID所對應的用戶。試想,如果沒有SessionID,當有兩個用戶同時進行註冊時,伺服器怎樣才能知道到底是哪個用戶提交了哪個表單呢。當然,SessionID還有很多其他的作用。
除了SessionID,在每個Session中還包含很多其他信息。但是對於編寫ASP或ASP .NET的程式設計師來說,最有用的還是可以通過訪問ASP/ASP .NET的內置Session對象,為每個用戶存儲各自的信息。例如我們想了解一下訪問我們網站的用戶瀏覽了幾個頁面,我們可能在用戶可能訪問到每個的頁面中加入:
<% If Session("PageViewed") = ""Then Session("PageViewed") = 1 Else Session("PageViewed") = Session("PageViewed") + 1 End If %>
通過以下這句話可以讓用戶得知自己瀏覽了幾個頁面:
<% Response.Write("You have viewed " & Session("PageViewed") & " pages") %>
可能有些讀者會問:這個看似像是數組的Session(“..”)是哪裡來的? 需要我定義嗎? 實際上,這個Session對象是具有ASP解釋能力的的WWW伺服器的內建對象。也就是說ASP的系統中已經給你定義好了這個對象,你只需要使用就行了。其中Session(“..")中的..就好像變數名稱,Session(“..")=$$中的$$就是變數的值了。你只需要寫上句話,在這個用戶的每個頁面中都可以訪問..變數中的值了。
其實ASP會話一共內建了7個對象,有Session、Application、Cookie、Response、Request、Server等。在其他的伺服器端腳本語言如JSP、PHP等中也有其類似的對象,只是叫法或者使用方法上不太一樣。
一般內容結構
變數名|類型:長度:值;
並用分號隔開每個變數。有些是可以省略的,比如長度和類型。
來看一下驗證程式,假設資料庫存儲的是用戶名和md5加密後的密碼:
//表單提交後...
$posts = $_POST;
// 清除一些空白符號
foreach ($posts as $key => $value)
{
$posts[$key] = trim($value);
}
$password = md5($posts["password"]);
$username = $posts["username"];
$query = "SELECT `username` FROM `user` WHERE `password` = '$password'";
// 取得查詢結果
$userInfo = $DB->getRow($query);
if (!empty($userInfo))
{
if ($userInfo["username"] == $username)
{
// 當驗證通過後,啟動session
session_start();
// 註冊登入成功的admin變數,並賦值true
$_SESSION["admin"] = true;
}
else
{
die("用戶名密碼錯誤");
}
}
else
{
die("用戶名密碼錯誤");
}
在需要用戶驗證的頁面啟動session,判斷是否登入:
// 防止全局變數造成安全隱患
$admin = false;
// 啟動會話,這步必不可少
session_start();
// 判斷是否登入
if (isset($_SESSION["admin"]) && $_SESSION["admin"] == true)
{
echo "您已經成功登入";
}
else
{
// 驗證失敗,將 $_session["admin"] 置為 false
$_SESSION["admin"] = false;
die("您無權訪問");
}
>
是不是很簡單呢?將 $_session 看成是存儲在伺服器端的數組即可,註冊的每一個變數都是數組的鍵,跟使用數組沒有什麼分別。
如果要登出系統怎么辦?銷毀 session 即可。
<?php
session_start();
// 這種方法是將原來註冊的某個變數銷毀
unset($_SESSION["admin"]);
// 這種方法是銷毀整個 session 檔案
session_destroy();
>
釋放當前在記憶體中已經創建的所有$_SESSION變數,但不刪除session檔案以及不釋放對應的session id
<?php
session_start();
session_unset();
session_destroy();
session_write_close();
setcookie(session_name(),'',0,'/');
session_regenerate_id(true);
?>
session_destroy()
刪除當前用戶對應的session檔案以及釋放session id,記憶體中的$_SESSION變數內容依然保留
因此,釋放用戶的session所有資源,需要順序執行如下代碼:
<?php
$_SESSION['user'] = ‘user1′;
session_unset();
session_destroy();
?>
Session能否像Cookie那樣設定生存周期呢?有了Session是否就完全拋棄Cookie呢?想說的是,結合Cookie來使用session才是最方便的。
如果客戶端沒有禁用Cookie,則Cookie在啟動Session會話的時候扮演的是存儲Session ID和session生存期的角色。
來手動設定session的生存期:
session_start();
// 保存一天
$lifeTime = 24 * 3600;
setcookie(session_name(),session_id(),time() + $lifeTime,"/");
>
// 保存一天
<?php
$lifeTime = 24 * 3600;
session_set_cookie_params($lifeTime);
session_start();
$_session["admin"] = true;
>
假設客戶端禁用Cookie怎么辦?沒辦法,所有生存周期都是瀏覽器進程了,只要關閉瀏覽器,再次請求頁面又得重新註冊Session。那么怎么傳遞Session ID呢? 通過URL或者通過隱藏表單來傳遞,PHP會自動將session ID傳送到URL 上,URL形如:?PHPSESSID=bba5b2a240a77e5b44cfa01d49cf9669,其中URL中的參數PHPSESSID就是Session ID了,可以使用$_GET來獲取該值,從而實現session ID頁面間傳遞。
// 保存一天
<?php
$lifeTime = 24 * 3600;
// 取得當前session 名,默認為PHPSESSID
$sessionName = session_name();
// 取得session ID
$sessionID = $_GET[$sessionName];
// 使用session_id()設定獲得的session ID
session_id($sessionID);
session_set_cookie_params($lifeTime);
session_start();
$_session["admin"] = true;
>
<?php
// 設定一個存放目錄
$savePath = "./session_save_dir/";
// 保存一天
$lifeTime = 24 * 3600;
session_save_path($savePath);
session_set_cookie_params($lifeTime);
session_start();
$_session["admin"] = true;
>
同 session_set_cookie_params(); 函式一樣,session_save_path()函式也必須在session_start()函式調用之前調用。
還可以將數組,對象存儲在session中。運算元組和操作一般變數沒有什麼區別,而保存對象的話,PHP會自動對對象進行序列化(也叫串列化),然後保存於session中。下面例子說明了這一點:
<?php
class person
{
var $age;
function output() {
echo $this->age;
}
function setAge($age) {
$this->age = $age;
}
}
>
setage.PHP
<?php
session_start();
require_once "person.PHP";
$person = new person();
$person->setAge(21);
$_session['person'] = $person;
echo "check here to output age";
>
output.PHP
<?php
// 設定回調函式,確保重新構建對象。
ini_set('unserialize_callback_func','mycallback');
function mycallback($classname) {
$classname . ".PHP";
}
session_start();
$person = $_session["person"];
// 輸出21
$person->output();
>
當執行setage.php檔案的時候,調用了setage()方法,設定了年齡為21,並將該狀態序列化後保存在session 中(PHP將自動完成這一轉換),當轉到output.php後,要輸出這個值,就必須反序列化剛才保存的對象,又因為在解序列化的時候需要實例化一個未定義類,所以定義了以後回調函式,自動包含person.PHP這個類檔案,因此對象被重構,並取得當前age的值為21,然後調用output()方法輸出該值。
如何防止session逾時
眾所周知,當用戶登錄網站後較長一段時間沒有與伺服器進行互動,將會導致伺服器上的用戶會話數據(即session)被銷毀。此時,當用戶再次操作網頁時,如果伺服器進行了session校驗,那么瀏覽器將會提醒用戶session逾時。
那么,如何解決用戶登錄後較長時間未操作而導致的session失效的問題呢?
導致這個問題的關鍵字有兩個:一個是「長時間」,一個是「未操作」。
1、如果用戶未操作的「長時間」超過了伺服器配置的session逾時時間,並導致session失效,那么我們延長session的逾時時間,讓用戶原來的「長時間」與逾時時間相比,變得不「長」,不就可以解決了嗎?
2、如果用戶是長時間「未操作」導致session失效,那么想辦法產生「操作」,讓用戶每隔一小段時間就「操作」一次,與伺服器產生互動,那么session自然也不會失效。一般情況下下,我們首先想到的是,通過改變伺服器的配置,延長伺服器的session逾時時間。例如,在Tomcat伺服器的web.xml檔案中有如下節點內容:
<session-config><session-timeout>30</session-timeout></session-config>
這裡的30表示session的逾時時間,單位為分鐘,如果用戶登錄後在30分鐘內沒有與伺服器互動,那么當前用戶的session將失效。我們可以配置一個更大的數值(比如60),就可以延長session的逾時時間,如果將該值改為0或負數的話,則表示session永不失效。
不過在實際的工作套用中,一味地上調session的逾時時間設定並不怎么常見,大多數需要實現該功能的網站都將解決問題的焦點集中在第二條思路上。例如:一些線上網站均採用定時刷新頁面的方法來防止session逾時。
定時刷新頁面,最常見的有兩種實現方式:一種是通過JavaScript+HTMLDOM,另一種則是通過meta標籤來實現。
1、JavaScript+HTMLDOM,示例代碼如下:
functionrefresh(seconds){
setTimeout("self.location.reload()",seconds*1000);
}
refresh(600);//調用方法啟動定時刷新,數值單位:秒。
2、通過meta標籤來實現(在頁面中添加meta標籤refresh也可以指定每隔指定時間就刷新當前頁面),示例代碼如下:
<metahttp-equiv="refresh"content="600"/>
meta標籤可以實現每過600秒就刷新一次當前頁面。
在兩種方案中,較好的為第二種,因為如果當前頁面是在IE瀏覽器的模式視窗中打開的,默認情況下,self.location.reload()方法將會失效,而refreshmeta標籤在IE模式視窗下仍然有效。
兩種方式都實現了刷新當前頁面,並且使用起來非常簡單,不過很遺憾的是,它們存在一種幾乎致命的缺陷。試想一下,如果在論壇發帖等需要用戶輸入內容的頁面,用戶花費較長的時間輸入了許多文本內容,可是突然遇到了一個定時頁面刷新,結果用戶輸入的所有內容都沒了,估計這個時候用戶連掐死你的心都有了……
<iframeid="hidden_iframe"style="display:none;"scrolling="no"frameborder="0"name="hidden_iframe"src="ping.php"></iframe>
此外,需要在伺服器上編寫對應的請求回響代碼,例如ping.php中可以編寫如下代碼:
<?php
//每隔600秒刷新當前頁面
echo'<html><head><metahttp-equiv="refresh"content="600"/></head><body></body></html>';
?>
另外一種則是使用JavaScriptImage對象來實現定時刷新,JavaScript代碼如下:
functionautoRefresh(seconds){
if(typeofperiod=="undefined"){//如果是第一次執行
period=seconds*1000;//定義全局變數period
varbodyDOM=document.getElementsByTagName("body")[0];
if(bodyDOM){
bodyDOM.innerHTML+='<imgid="auto_refresh_img"src=""style="display:none"/>';//添加隱藏的圖片
imgDOM=document.getElementById("auto_refresh_img");//定義全局Image對象
}
}
if(typeofimgDOM!="undefined"){
imgDOM.src="ping.php?sid="+newDate().getTime();//防止快取
setTimeout("autoRefresh("+seconds+")",period);
}
}
autoRefresh(600);//調用方法啟動定時刷新
和使用iframe來實現定時刷新一樣,使用JavaScriptImage對象實現定時刷新,也需要在伺服器端編寫類似的請求回響代碼。伺服器的回響可以是文字等非圖片內容,非圖片內容只會造成圖像載入失敗,而圖像標籤本身就是隱藏的,不管是載入成功還是失敗都不會顯示,畢竟我們的主要目的是傳送請求給伺服器,讓伺服器保持session處於活動狀態。
當然,還可以使用Ajax來實現定時刷新,不過使用Image對象會更好一些,因為有些老式瀏覽器的JavaScript無法實現Ajax,但是卻可以使用Image對象。此外,使用Ajax需要編寫更多的代碼來處理XMLHttpRequest等對象的活動。
在兩種方式中,各有其優缺點。
使用iframe標籤實現定時刷新的優點是:不需要編寫JavaScript代碼,可以在瀏覽器禁用JavaScript的情況下實現定時刷新;其缺點是:在某些不支持iframe標籤的老式瀏覽器中沒有效果,此外,iframe標籤在瀏覽器中新增加了一個獨立的頁面,即使沒有顯示出來,不過其內部解析的window、document等對象仍然存在,占用的瀏覽器記憶體相對較多。
使用Image對象的優點是:與iframe相比,占用的記憶體相對較少,支持Image的瀏覽器也相對較多(現代瀏覽器均支持);缺點是:在瀏覽器禁用JavaScript的情況下就毫無用武之地了。
開發人員應根據實際需求情況來確定使用何種實現方式更好。此外,伺服器在回響定時刷新的請求時,在滿足要求的情況下,應返回儘可能少的數據,以節省頻寬。
比較分析
由於HTTP協定無狀態的缺陷。WEB的設計者們提出了Cookie和Session兩種解決機制。通過對兩者的比較分析,指出了它們的聯繫與區別。
有效期
PHP中的session有效期默認是1440秒(24分鐘)【weiweiok 註:php5里默認的是180分】,也就是說,客戶端超過24分鐘沒有刷新,當前session就會失效。很明顯,這是不能滿足需要的。
一個已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存儲到數 據庫,這樣可以通過SQL語句來刪除所有過期的session,精確地控制session的有效期。這也是基於PHP的大型網站常用的方法。但是,一般的小型網站,似乎沒有必要這么勞師動眾。
但是一般的Session的生命期有限,如果用戶關閉了瀏覽器,就不能保存Session的變數了!那么怎么樣可以實現Session的永久生命期呢?
大家知道,Session儲存在伺服器端,根據客戶端提供的SessionID來得到這個用戶的檔案,然後讀取檔案,取得變數的值,SessionID可以 使用客戶端的Cookie或者Http1.1協定的Query_String(就是訪問的URL的“?”後面的部分)來傳送給伺服器,然後伺服器讀取Session的目錄……
1、session.use_cookies:默認的值是“1”,代表SessionID使用Cookie來傳遞,反之就是使用Query_String來傳遞;
2、session. name:這個就是SessionID儲存的變數名稱,可能是Cookie,也可能是Query_String來傳遞,默認值是“PHPSESSID”;
3、session.cookie_lifetime:這個代表SessionID在客戶端Cookie儲存的時間,默認是0,代表瀏覽器一關閉SessionID就作廢……就是因為這個所以Session不能永久使用!
4、session.gc_maxlifetime:這個是Session數據在伺服器端儲存的時間,如果超過這個時間,那么Session數據就自動刪除!
ASP的開發人員都正在使用Session這一強大的功能,但是在使用的過程中卻發現了ASP Session有以下缺陷:
進程依賴性
ASP Session狀態存於IIS的進程中,也就是inetinfo.exe這個程式。所以當inetinfo.exe進程崩潰時,這些信息也就丟失。另外,重起或者關閉IIS服務都會造成信息的丟失。
Session狀態使用範圍的局限性
當一個用戶從一個網站訪問到另外一個網站時,這些Session信息並不會隨之遷移過去。例如:新浪網站的WWW伺服器可能不止一個,一個用戶登錄之後要去各個頻道瀏覽,但是每個頻道都在不同的伺服器上,如果想在這些WWW伺服器共享Session信息怎么辦呢?
Cookie的依賴性
實際上客戶端的Session信息是存儲在Cookie中的,如果客戶端完全禁用掉了Cookie功能,他也就不能享受到了Session提供的功能了。
主要特點
注意這裡的Session的含義,它與傳統意思上web層的HttpSession並沒有關係,Hibernate Session之於Hibernate,相當於JDBC Connection相對與JDBC。
Session有以下的特點:
1、不是執行緒安全的,應該避免多個執行緒共享同一個Session實例;
2、Session實例是輕量級的,所謂輕量級:是指他的創建和刪除不需要消耗太多資源;
3、Session對象內部有一個快取,被稱為Hibernate第一快取,他存放被當前工作單元中載入的對象,每個Session實例都有自己的快取。
org.hibernate Interface Session
public interface Session extends Serializable : 是一個Java application 和Hibernate之間主要的運行時接口,這是執行持久化服務的中心API。
主要方法:
public Transaction beginTransaction() throws HibernateException:返回和當前Session對象相互聯繫的Transaction對象(表示在資料庫中重新開始一個事務)
public Transaction getTransaction():返回和當前session聯繫的Transaction對象
public Connection connection close() throws HibernateExcepton:結束當前的Session對象
public void clear() :清空Session,清除所有保存在當前Session快取中的實體對象,終止所有正在執行的方法(eg: save(),update(),delete() .....)
public Serializable save(Object object)throws HibernateException 對當前參數指定的對象進行持久化(系統會首先賦予參數對象一個標識符OID),他相當於insert語句 後面在詳細介紹
public Connection connection() throws HibernateException 得到當前Session 中包含的Connection對象
public boolean contains(Object object):判斷參數給出的對象(持久化類)是否在當前Session的快取中
public void evict(Object object) throws HibernateException :將參數給出的Object從當前Session對象類中刪除,使這個對象從持久態變成游離態,這種狀態的改變不會引起對資料庫的同步
public Object load(Class theclass,Serializable id) throws HibernateException 返回第一個參數指定類對應的表中,第二個參數指定的行(第二個參數就是要取得對象的OID,他對應表中主鍵列的值)
public void update(Object object) throws HibernateException :更新一個對象到資料庫中
public void delete (Object object)throws HibernateException:從資料庫中刪除和參數指定的對象對應的記錄
public Object get(Class class,Serializable id) throws HibernateException:和load()方法一樣區別在於,如果資料庫表中沒有對應的記錄,get()方法返回null,load()方法將報異常
相關接口
Transaction接口是Hibernate的資料庫事務接口,用於管理事務,他對底層的事務作出了封裝,用戶可以使用Transaction對象定義自己的對資料庫的原子操作,底層事務包括:JDBC API,JTA(Java Transaction API)。
一個Transaction對象的事務可能會包括多個對資料庫進行的操作
org.hibernate Interface Transaction
public interface Transaction
常用方法
public void commit() throws HibernateException 刷新當前的Session以及結束事務的工作,這個方法將迫使資料庫對當前的事務進行提交
public void rollback() throws HibernateException :強迫回滾當前事務
public boolean isActive() throws HibernateException:這個事務是否存活
----------------------------------------------------------------------------------------
Session:當中包含一個Connection對象
Connection c =session.getConnection();
Session的快取用於臨時保存持久化的對象,等到一定時候,再將快取中的對象保存到資料庫中。
Configuration config=new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionfactory=config.buildSessionFactory();
Session session=sessionfactory.openSession();
Transaction tx=session.beginTransaction();
try
{
session.save();
tx.commit();
}
catch(Exception e)
{
if(tx!=null) tx.rollback();
}
finally
{
session.close ();
}