1
2
3
4
5
6
|
<?php
// 啓動 Session
session_start();
// 聲明一個名爲 admin 的變量,並賦空值。
$_SESSION
[
"admin"
] = null;
?>
|
若是你使用了 Seesion,或者該 PHP 文件要調用 Session 變量,那麼就必須在調用 Session 以前啓動它,使用 session_start() 函數。其它都不須要你設置了,PHP 自動完成 Session 文件的建立。
執行完這個程序後,咱們能夠到系統臨時文件夾找到這個 Session 文件,通常文件名形如:sess_4c83638b3b0dbf65583181c2f89168ec,後面是 32 位編碼後的隨機字符串。用編輯器打開它,看一下它的內容:php
1
|
admin|N;
|
通常該內容是這樣的結構:數據庫
1
|
變量名|類型:長度:值;
|
並用分號隔開每一個變量。有些是能夠省略的,好比長度和類型。
咱們來看一下驗證程序,假設數據庫存儲的是用戶名和 md5 加密後的密碼:
login.php數組
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?php
// 表單提交後...
$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' AND `username` = '$username'"
;
// 取得查詢結果
$userInfo
=
$DB
->getRow(
$query
);
if
(!
empty
(
$userInfo
)) {
// 當驗證經過後,啓動 Session
session_start();
// 註冊登錄成功的 admin 變量,並賦值 true
$_SESSION
[
"admin"
] = true;
}
else
{
die
(
"用戶名密碼錯誤"
);
}
?>
|
咱們在須要用戶驗證的頁面啓動 Session,判斷是否登錄:瀏覽器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
// 防止全局變量形成安全隱患
$admin
= false;
// 啓動會話,這步必不可少
session_start();
// 判斷是否登錄
if
(isset(
$_SESSION
[
"admin"
]) &&
$_SESSION
[
"admin"
] === true) {
echo
"您已經成功登錄"
;
}
else
{
// 驗證失敗,將 $_SESSION["admin"] 置爲 false
$_SESSION
[
"admin"
] = false;
die
(
"您無權訪問"
);
}
?>
|
是否是很簡單呢?將 $_SESSION 當作是存儲在服務器端的數組便可,咱們註冊的每個變量都是數組的鍵,跟使用數組沒有什麼分別。
若是要登出系統怎麼辦?銷燬 Session 便可。安全
1
2
3
4
5
6
7
|
<?php
session_start();
// 這種方法是將原來註冊的某個變量銷燬
unset(
$_SESSION
[
'admin'
]);
// 這種方法是銷燬整個 Session 文件
session_destroy();
?>
|
Session 可否像 Cookie 那樣設置生存週期呢?有了 Session 是否就徹底拋棄 Cookie 呢?我想說,結合 Cookie 來使用 Session 纔是最方便的。
Session 是如何來判斷客戶端用戶的呢?它是經過 Session ID 來判斷的,什麼是 Session ID,就是那個 Session 文件的文件名,Session ID 是隨機生成的,所以能保證惟一性和隨機性,確保 Session 的安全。通常若是沒有設置 Session 的生存週期,則 Session ID 存儲在內存中,關閉瀏覽器後該 ID 自動註銷,從新請求該頁面後,從新註冊一個 Session ID。
若是客戶端沒有禁用 Cookie,則 Cookie 在啓動 Session 會話的時候扮演的是存儲 Session ID 和 Session 生存期的角色。
咱們來手動設置 Session 的生存期:服務器
1
2
3
4
5
6
|
<?php
session_start();
// 保存一天
$lifeTime
= 24 * 3600;
setcookie(session_name(), session_id(), time() +
$lifeTime
,
"/"
);
?>
|
其實 Session 還提供了一個函數 session_set_cookie_params(); 來設置 Session 的生存期的,該函數必須在 session_start() 函數調用以前調用:cookie
1
2
3
4
5
6
7
|
<?php
// 保存一天
$lifeTime
= 24 * 3600;
session_set_cookie_params(
$lifeTime
);
session_start();
$_SESSION
[
"admin"
] = true;
?>
|
若是客戶端使用 IE 6.0 , session_set_cookie_params(); 函數設置 Cookie 會有些問題,因此咱們仍是手動調用 setcookie 函數來建立 cookie。
假設客戶端禁用 Cookie 怎麼辦?沒辦法,全部生存週期都是瀏覽器進程了,只要關閉瀏覽器,再次請求頁面又得從新註冊 Session。那麼怎麼傳遞 Session ID 呢?經過 URL 或者經過隱藏表單來傳遞,PHP 會自動將 Session ID 發送到 URL 上,URL 形如:http://www.openphp.cn/index.php?PHPSESSID=bba5b2a240a77e5b44cfa01d49cf9669,其中 URL 中的參數 PHPSESSID 就是 Session ID了,咱們可使用 $_GET 來獲取該值,從而實現 Session ID 頁面間傳遞。session
<?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; ?>
對於虛擬主機來講,若是全部用戶的 Session 都保存在系統臨時文件夾裏,將給維護形成困難,並且下降了安全性,咱們能夠手動設置 Session 文件的保存路徑,session_save_path() 就提供了這樣一個功能。咱們能夠將 Session 存放目錄指向一個不能經過 Web 方式訪問的文件夾,固然,該文件夾必須具有可讀寫屬性。編輯器
1
2
3
4
5
6
7
8
9
10
|
<?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 中。下面例子說明了這一點:
person.php函數
1
2
3
4
5
6
7
8
9
10
11
|
<?php
class
person {
var
$age
;
function
output() {
echo
$this
->age;
}
function
setAge(
$age
) {
$this
->age =
$age
;
}
}
?>
|
setage.php
1
2
3
4
5
6
7
8
|
<?php
session_start();
require_once
'person.php'
;
$person
=
new
person();
$person
->setAge(21);
$_SESSION
[
'person'
] =
$person
;
echo
'<a href='
output.php
'>check here to output age</a>'
;
?>
|
output.php
1
2
3
4
5
6
7
8
9
10
11
|
<?php
// 設置回調函數,確保從新構建對象。
ini_set
(
'unserialize_callback_func'
,
'mycallback'
);
function
mycallback(
$classname
) {
include_once
$classname
.
'.php'
;
}
session_start();
$person
=
$_SESSION
[
'person'
];
// 輸出 21
$person
->output();
?>
|
當咱們執行 setage.php 文件的時候,調用了 setage() 方法,設置了年齡爲 21,並將該狀態序列化後保存在 Session 中(PHP 將自動完成這一轉換),當轉到 output.php 後,要輸出這個值,就必須反序列化剛纔保存的對象,又由於在解序列化的時候須要實例化一個未定義類,因此咱們定義了之後回調函數,自動包含 person.php 這個類文件,所以對象被重構,並取得當前 age 的值爲 21,而後調用 output() 方法輸出該值。 另外,咱們還可使用 session_set_save_handler 函數來自定義 Session 的調用方式。