PHP session的詳細分析

來源:互聯網
上載者:User

  

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的案例:
<?php
// 初始化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 情況下沒有達到想要的效果。目前發現在<a href='xx.php'>xx</a>中正常。)
2、手動通過URL傳值、隱藏表單傳遞session id。
3、用檔案、資料庫等形式儲存session_id,在跨頁過程中手動調用。
下面舉例說明:
第一種情況:
page1.php
<?php
session_start();
$_SESSION['var1']="中華人民共和國";
$url="<a href="."\"s2.php\">下一頁</a>";
echo $url;
?>
page2.php
<?php
session_start();
echo "傳遞的session變數var1的值為:".$_SESSION['var1'];
?>
運行以上代碼,在用戶端cookie正常的情況下,應該可以在得到結果“中華人民共和國”。
現在你手動關閉用戶端的cookie,再運行,可能得不到結果了吧。如果得不到結果,再“設定php.ini中的session.use_trans_sid = 1或者編譯時間開啟開啟了--enable-trans-sid選項”,又得到結果“中華人民共和國”

第二種途徑:
s1.php
<?php
session_start();
$_SESSION['var1']="中華人民共和國";
$sn = session_id();

//PHP5定義了一個常量SID來表示session_id(),$url還可以寫成$url='<a href="page2.php?' . SID . '">下一頁</a>';

$url="<a href="."\"s2.php?s=".$sn."\">下一頁</a>";  

echo $url;
?>

s2.php

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

第三種途徑:
login.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Login</title>
<meta http-equiv="Content-Type" content="text/html; charset=??????">
</head>
<body>
請登入:
<form name="login" method="post" action="mylogin1.php">
使用者名稱:<input type="text" name="name"><br>
口 令:<input type="password" name="pass"><br>
<input type="submit" value="登入">
</form>
</body>
</html>

mylogin1.php

<?php
$name=$_POST['name'];
$pass=$_POST['pass'];
if(!$name || !$pass) {
echo "使用者名稱或密碼為空白,請<a href=\"login.html\">重新登入</a>";
die();
}
if (!($name=="laogong" && $pass=="123")) {
echo "使用者名稱或密碼不正確,請<a href=\"login.html\">重新登入</a>";
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 "已登入<br>";
echo "<a href=\"mylogin2.php\">下一頁</a>";
?>

mylogin2.php
<?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 "請<a href=\"login.html\">登入</a>後瀏覽";
die();
}
?>

4.關於多伺服器共用同一session的解決辦法

   稍大一些的網站,通常都會有好幾個伺服器,每個伺服器運行著不同功能的模組,使用不同的次層網域,而一個整體性強的網站,使用者系統是統一的,即一套使用者名稱、密碼在整個網站的各個模組中都是可以登入使用的。各個伺服器共用使用者資料是比較容易實現的,只需要在後端放個資料庫伺服器,各個伺服器通過統一介面對使用者資料進行訪問即可。但還存在一個問題,就是使用者在這個伺服器登入之後,進入另一個伺服器的別的模組時,仍然需要重新登入,這就是一次登入,全部通行的問題,映射到技術上,其實就是各個伺服器之間如何?共用 SESSION
資料的問題。

想要共用 SESSION 資料,那就必須實現兩個目標:一個是各個伺服器對同一個用戶端產生的 SESSION ID 必須相同,並且可通過同一個 COOKIE 進行傳遞,也就是說各個伺服器必須可以讀取同一個名為 PHPSESSID 的 COOKIE;另一個是 SESSION 資料的儲存方式/位置必須保證各個伺服器都能夠訪問到。簡單地說就是多伺服器共用用戶端的 SESSION ID,同時還必須共用伺服器端的 SESSION 資料。

第一個目標的實現其實很簡單,只需要對 COOKIE 的域(domain)進行特殊地設定即可,預設情況下,COOKIE 的域是當前伺服器的網域名稱/IP 位址,而域不同的話,各個伺服器所設定的 COOKIE 是不能相互訪問的,如
www.aaa.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 資料了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.