PHP session的詳細分析_PHP教程

來源:互聯網
上載者:User
1.PHP session 工作原理
Session檔案儲存於伺服器端,,預設情況下SESSION 檔案儲存的目錄由session.save_path 指定,檔案名稱以sess_ 為首碼,後跟SESSION ID,如:sess_c72665af28a8b14c0fe11afe3b59b51b。可以根據用戶端提供的session id來得到使用者的檔案,取得變數的值,session id可以使用用戶端的Cookie或者Http1.1協議的Query_String(就是訪問的URL的“?”後面的部分)來傳送給伺服器,然後伺服器讀取Session的目錄。也就是說,session id是取得儲存在服務上的session變數的身份證。
當代碼session_start();啟動並執行時候,就在伺服器上產生了一個session檔案,隨之也產生了與之唯一對應的一個session id,定義session變數以一定形式儲存在剛才產生的session檔案中。通過session id,可以取出定義的變數。跨頁後,為了使用session,你必須又執行session_start();將又會產生一個session檔案,與之對應產生相應的session id,用這個session id是取不出前面提到的第一個session檔案中的變數的,因為這個session id不是開啟它的“鑰匙”。如果在session_start();之前加代碼session_id($session id);將不產生新的session檔案,直接讀取與這個id對應的session檔案。
2. Session常見函數及用法
2.1 Session_start(): 開始一個會話或者返回已經存在的會話。
這個函數沒有參數,且傳回值均為true。如果你使用基於cookie的session,那麼在使用Session_start()之前瀏覽器不能有任何輸出.可以在php.ini裡啟動session.auto_start=1,這樣就無需每次使用session之前都要調用session_start()。但啟用該選項也有一些限制,如果確實啟用了session.auto_start,則不能將對象放入會話中,因為類定義必須在啟動會話之前載入以在會話中重建對象。
2.2 註冊SESSION變數 :
PHP5使用$_SESSION[‘xxx’]=xxx註冊SESSION全域變數。注意session_register(),
session_unregister ,session_is_registered在php5下不再使用,除非在php.ini裡把
register_globle設為on,不過出於安全考慮,強烈建議關閉register_globle。
HTTP_SESSION_VARS也不提倡使用了,官方建議用$_SESSION代替之。
Page1.php
session_start(); //使用SESSION前必須調用該函數。
$_SESSION[‘name’]=”我是黑旋風李逵!”; //註冊一個SESSION變數
$_SESSION[‘passwd’]=”mynameislikui”;
$_SESSION[‘time’]=time();
//如果用戶端支援cookie,可通過該連結傳遞session到下一頁。
echo '
通過COOKIE傳遞SESSION';
//用戶端不支援cookie時,使用該辦法傳遞session.
echo '
通過URL傳遞SESSION';
Page2.php
session_start();
echo $_SESSION['name'];
echo $_SESSION['passwd'];
echo date('Y m d H:i:s', $_SESSION['time']);
echo '
返回上一頁';
?>
2.3 session_id ([ string $id ] ):Get and/or set the current session id
php5中既可以使用session_id(),也可以通過附加在url上的SID取得當前會話的session_id和session_name。
如果session_id()有具體指定值的話(即指定了參數$id),將取代當前的session_id值。使用該函數前必須啟動會話:session_start();
例子:手動設定Session 的生存期:
session_start();
// 儲存一天
$lifeTime = 24 * 3600;
setcookie(session_name(), session_id(), time() + $lifeTime, "/");
?>
其實Session 還提供了一個函數session_set_cookie_params(); 來設定Session 的生存期的,該函數必須在session_start() 函數調用之前調用:
// 儲存一天
$lifeTime = 24 * 3600;
session_set_cookie_params($lifeTime);
session_start();
$_SESSION["admin"] = true;
?>
如果用戶端使用IE 6.0 ,session_set_cookie_params(); 函數設定Cookie 會有些問題,所以我們還是手動調用setcookie 函數來建立cookie。
2.4 檢查session是否存在?
在以往的php版本中通常使用session_is_register()檢查session是否存在,如果您使用$_SESSION[‘XXX’]=XXX來註冊會話變數,則session_is_register()函數不再起作用。你可以使用
isset($_SESSION[‘xxx’])來替代。
2.5更改session_id session_regenerate_id([bool $delete_old_session]) 更改成功則返回true,失敗則返回false。
使用該函數可以為當前session更改session_id,但預設不改變當前session的其他資訊,除非$delete_old_session為true。例如:
session_start();
$old_sessionid = session_id();
session_regenerate_id();
$new_sessionid = session_id();
echo "原始SessionID: $old_sessionid
";
echo "新的SessionID: $new_sessionid
";
echo"
";
print_r($_SESSION);
echo"
";
?>
2.6 session_name() 返回當前session的name或改變當前session的name。如果要改變當前session的name,必須在session_start()之前調用該函數。注意:session_name不能只由數字組成,它至少包含一個字母。否則會在每時每刻都產生一個新的session id.
session改名樣本:
$previous_name = session_name("WebsiteID");
echo "新的session名為:$previous_name
";
?>

2.7 如何刪除session
(1) unset ($_SESSION['xxx']) 刪除單個session,unset($_SESSION['xxx']) 用來unregister一個登入的session變數。其作用和session_unregister()相同。session_unregister()在PHP5中不再使用,可將之打入冷宮。
unset($_SESSION) 此函數千萬不可使用,它會將全域變數$_SESSION銷毀,而且還沒有可行的辦法將其恢複。使用者也不再可以註冊$_SESSION變數。
(2) $_SESSION=array() 刪除多個session
(3) session_destroy()結束當前的會話,並清空會話中的所有資源。該函數不會unset和當前session相關的全域變數(globalvariables),也不會刪除用戶端的session cookie.PHP預設的session是基於cookie的,如果要刪除cookie的話,必須藉助setcookie()函數。
下面是PHP官方關於刪除session的案例:
// 初始化session.
session_start();
/*** 刪除所有的session變數..也可用unset($_SESSION[xxx])逐個刪除。****/
$_SESSION = array();
/***刪除sessin id.由於session預設是基於cookie的,所以使用setcookie刪除包含session id的cookie.***/
if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000, '/');
}
// 最後徹底銷毀session.
session_destroy();
?>
由此我們可以得出刪除Session的步驟:
①session_start()
②$_SESSION=array()/unset($_SESSION['xxx'])
③session_destroy()

3. Session跨頁傳遞問題:
3.1有兩種方法傳遞一個會話ID:cookie URL 參數
會話模組支援這兩種方法。cookie 更最佳化,但由於不總是可用,也提供替代的方法。第二種方法直接將會話ID 嵌入到URL 中間去。
PHP 可以透明地轉換頁面之間的連結。如果使用低於PHP 4.2的版本,則需要手工在編譯PHP 時啟用,在Unix 下,用--enable-trans-sid 配置選項。如果此配置選項和運行時選項session.use_trans_sid 都被啟用(修改php.ini),相對URI 將被自動修改為包含會話ID。
Note: 非相對的URL 被假定為指向外部網站,因此沒有附加SID,因為這可能是個安全隱患將SID 泄露給不同的伺服器。
另外,也可以用常量SID。如果用戶端沒有發送會話cookie ,則SID 的格式為session_name=session_id,否則就為一個Null 字元串。因此可以無條件將其嵌入到URL 中去。
3. 2 解決session跨頁傳遞問題的三條途徑
①用戶端禁用了cookie。
②瀏覽器出現問題,暫時無法存取cookie
③php.ini中的session.use_trans_sid = 0或者編譯時間沒有開啟--enable-trans-sid選項
當用戶端的Cookie被禁用或出現問題時,PHP會自動把session id附著在URL中,這樣再通過session id就能跨頁使用session變數了。但這種附著也是有一定條件的:“php.ini中的session.use_trans_sid = 1或者編譯時間開啟開啟了--enable-trans-sid選項”;
明白了以上的道理,我們就可以得出解決session跨頁傳遞問題的三條途徑:
1、設定php.ini中的session.use_trans_sid = 1或者編譯時間開啟開啟了--enable-trans-sid選項,讓PHP自動跨頁傳遞session id。
(有人說:但在測試的時候,修改php.ini哪種方式在頁面中用header('location: xx.php') 和javascript window.location=xx.php 情況下沒有達到想要的效果。目前發現在xx中正常。)
2、手動通過URL傳值、隱藏表單傳遞session id。
3、用檔案、資料庫等形式儲存session_id,在跨頁過程中手動調用。
下面舉例說明:
第一種情況:
page1.php
session_start();
$_SESSION['var1']="中華人民共和國";
$url="下一頁";
echo $url;
?>
page2.php
session_start();
echo "傳遞的session變數var1的值為:".$_SESSION['var1'];
?>
運行以上代碼,在用戶端cookie正常的情況下,應該可以在得到結果“中華人民共和國”。
現在你手動關閉用戶端的cookie,再運行,可能得不到結果了吧。如果得不到結果,再“設定php.ini中的session.use_trans_sid = 1或者編譯時間開啟開啟了--enable-trans-sid選項”,又得到結果“中華人民共和國”
第二種途徑:
s1.php
session_start();
$_SESSION['var1']="中華人民共和國";
$sn = session_id();
//PHP5定義了一個常量SID來表示session_id(),$url還可以寫成$url='下一頁';
$url="下一頁";
echo $url;
?>


s2.php
session_id($_GET['s']);
session_start();
echo "傳遞的session變數var1的值為:www.2cto.com".$_SESSION['var1'];
?>

第三種途徑:
login.html



Login



請登入:




mylogin1.php
$name=$_POST['name'];
$pass=$_POST['pass'];
if(!$name || !$pass) {
echo "使用者名稱或密碼為空白,請重新登入";
die();
}
if (!($name=="laogong" && $pass=="123")) {
echo "使用者名稱或密碼不正確,請重新登入";
die();
}
//註冊使用者
ob_start(); // Turn on output buffering
session_start();
$_SESSION['user']= $name;
$psid=session_id();
$fp=fopen("e:\\tmp\\phpsid.txt","w+");
fwrite($fp,$psid);
fclose($fp);
//身分識別驗證成功,進行相關操作
echo "已登入
";
echo "下一頁";
?>
mylogin2.php

$fp=fopen("e:\\tmp\\phpsid.txt","r");
$sid=fread($fp,1024);
fclose($fp);
session_id($sid);
session_start();
if(isset($_SESSION['user']) && $_SESSION['user']="laogong" ) {
echo "已登入!";
}
else {
//成功登入進行相關操作
echo "未登入,無權訪問";
echo "請登入後瀏覽";
die();
}
?>
4.關於多伺服器共用同一session的解決辦法
稍大一些的網站,通常都會有好幾個伺服器,每個伺服器運行著不同功能的模組,使用不同的次層網域,而一個整體性強的網站,使用者系統是統一的,即一套使用者名稱、密碼在整個網站的各個模組中都是可以登入使用的。各個伺服器共用使用者資料是比較容易實現的,只需要在後端放個資料庫伺服器,各個伺服器通過統一介面對使用者資料進行訪問即可。但還存在一個問題,就是使用者在這個伺服器登入之後,進入另一個伺服器的別的模組時,仍然需要重新登入,這就是一次登入,全部通行的問題,映射到技術上,其實就是各個伺服器之間如何?共用SESSION 資料的問題。
想要共用SESSION 資料,那就必須實現兩個目標:一個是各個伺服器對同一個用戶端產生的SESSION ID 必須相同,並且可通過同一個COOKIE 進行傳遞,也就是說各個伺服器必須可以讀取同一個名為PHPSESSID 的COOKIE;另一個是SESSION 資料的儲存方式/位置必須保證各個伺服器都能夠訪問到。簡單地說就是多伺服器共用用戶端的SESSION ID,同時還必須共用伺服器端的SESSION 資料。
第一個目標的實現其實很簡單,只需要對COOKIE 的域(domain)進行特殊地設定即可,預設情況下,COOKIE 的域是當前伺服器的網域名稱/IP 位址,而域不同的話,各個伺服器所設定的COOKIE 是不能相互訪問的,如www.2cto.com 的伺服器是不能讀寫www.bbb.com 伺服器設定的COOKIE 的。這裡我們所說的同一網站的伺服器有其特殊性,那就是他們同屬於同一個一級域,如:aaa.infor96.com 和www.infor96.com 都屬於域.infor96.com,那麼我們就可以設定COOKIE 的域為.infor96.com,這樣aaa.infor96.com、www.infor96.com 等等都可以訪問此COOKIE。PHP 代碼中的設定方法如下:
CODE:
ini_set('session.cookie_domain', '.infor96.com');
第二個目標的實現可以使用檔案分享權限設定方式,如NFS 方式,但設定、操作上有些複雜。我們可以參考先前所說的統一使用者系統的方式,即使用資料庫來儲存SESSION 資料,這樣各個伺服器就可以方便地訪問同一個資料來源,擷取相同的SESSION 資料了。
關於如何將session放入資料庫可以見《php 程式設計》,和以下網頁
http://www.eb163.com/article.php?id=75&PHPSESSID=d226cc07cec0580ec7dad47119ee4667摘自 河大李信的Crazy Coding人生


http://www.bkjia.com/PHPjc/478394.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/478394.htmlTechArticle1.PHP session 工作原理 Session檔案儲存於伺服器端,,預設情況下SESSION 檔案儲存的目錄由session.save_path 指定,檔案名稱以sess_ 為首碼,後跟S...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.