Session 類
Session 類可以使用戶在瀏覽您的網站時,維持他們的狀態(tài)并跟蹤他們的行為。 Session 類將每個用戶的 session 信息序列化(serialize)后存儲到到 cookie 中(并同時進行加密)。 您還可以將 session 數據存儲到數據庫中來增強安全性,但是這時要求存儲在用戶 cookie 中的 session ID 值能與數據庫中存儲的用戶 session ID 值相匹配。程序默認只在 cookie 中存儲 session。如果您在要在數據庫中存儲 session 的話,需要按照下面指示的方法,在您的數據庫中創(chuàng)建需要的數據表。
注意: Session類并不使用PHP本身的session,而是使用類自己的session,這樣做,可以給開發(fā)者提供更大的彈性。
Note: 即使沒有使用加密會話,你也需要在配置文件里設置一個加密密鑰。這將有助于防止偽造會話數據。
初始化 Session
Sessions會在每個頁面載入后開始運行,所以session類必須首先被初始化。您可以在控制器中初始化,也可以在系統(tǒng)中自動加載(譯者注:在autoload.php設定)。session類的絕大部分都會在后臺運行,所以初始化session時,它session數據會被自動讀取、創(chuàng)建和更新。
要在您的控制器構造函數中初始化session類,您可以使用 $this->load->library 函數:
$this->load->library('session');
一旦被載入, session就可以這樣使用: $this->session
Sessions 是怎樣工作的?
當頁面載入后,session類就會檢查用戶的cookie中是否存在有效的session數據。如果session數據不存在(或者已經過期),那么就會創(chuàng)建一個新的session并把他保存在cookie中。如果session數據存在,那么他的信息就會被更新,同時cookie也會被同時更新。每次更新都會重新生成session_id的值。
對于您來說,需要知道的非常重要的一點就是,session類一旦被初始化,它就會自動運行。對于后面的事情,您可以完全不作理會。正如您將會在下面看到的一樣,您可以正常使用session來工作,甚至還可以添加自己的session數據,而在這一切的過程中,讀、寫和更新的操作都是自動完成的。
Session 數據是什么?
一個 session 是由一個包括下列信息的數組組成的:
- 唯一的用戶Session ID (這是一個平均信息量統(tǒng)計出來的非常堅固的隨機字符串,使用MD5加密,默認是每五分鐘就重新生成一次。
- 用戶的 IP 地址
- 用戶瀏覽器信息(取前120個字符)
- 最新的一個活躍時間戳.
以上數據將會用以下數組格式序列化并存到cookie里:
[array]
(
?????'session_id'????=> random hash,
?????'ip_address'????=> 'string - user IP address',
?????'user_agent'????=> 'string - user agent data',
?????'last_activity' => timestamp
)
如果你將加密設置開啟,serialized 的數組會先被加密,然后存入cookie中。這會讓數據不容易被看到和修改,從而提高安全性。從這里可以找到更多關于加密的信息。Session類會自動負責初始化和數據加密。
注意: 默認情況下, Session Cookie 每隔 5 分鐘才會更新一次,這樣會減少對處理器的負荷。如果你重復的裝載頁面, 你會發(fā)現(xiàn)"上次活動"的時間在五分鐘,或多余五分鐘的時候才會變化,也就是 cookie 上次被寫入的時間。 這個時間可以通過設置 application/config/config.php 文件里的 $config['sess_time_to_update'] 行來改變。
取得 Session 數據
可以通過如下的函數來得到 session 數組的任何信息:
$this->session->userdata('item');
item 是數組里的相對應數據的索引。例如,想要獲得 session ID, 你要使用如下的代碼:
$session_id = $this->session->userdata('session_id');
注意: 如果你的目標數據不存在的話,這個函數會返回 FALSE (布爾值boolean)。
添加自定義的 Session 數據
session 數組的一個非常有用的用途是你可以向它里面添加你自己的數據,這些數據會被保存在用戶的 cookie 中。這樣做的原因是什么呢?看看這個例子:
假設,有個特定用戶登陸到你的網站, 當他通過檢測后 你可以添加他的用戶名和電子郵件到 session cookie 中,這些信息可以在不去訪問數據庫的情況下,當成全局量來使用。
通過以下函數,你可以傳遞一個新的用戶數組到 session 數組中:
$this->session->set_userdata($array);
$array 是一個結合數組,用來存儲你的新數據。例如 :
$newdata = array(
???????????????????'username'? => 'johndoe',
???????????????????'email'?????=> 'johndoe@some-site.com',
???????????????????'logged_in' => TRUE
???????????????);
$this->session->set_userdata($newdata);
如果使用下面 set_userdata()函數的寫法,可以每次只添加一個用戶數據。
$this->session->set_userdata('some_name', 'some_value');
注意: Cookies 只能存儲 4KB 的數據, 使用時要小心超出它的容量。特別指出的是,加密會產生比原數據更長的數據字符串,所以一定要當心你要存放數據的大小。
取得所有 Session 數據
用下面的這種方式可以得到一個所有Session用戶數據的數組:
$this->session->all_userdata()
代碼將返回一個類似這樣的關聯(lián)數組:
Array ( [session_id] => 4a5a5dca22728fb0a84364eeb405b601 [ip_address] => 127.0.0.1 [user_agent] => Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; [last_activity] => 1303142623 )
刪除 Session 數據
正如使用 set_userdata() 是用來添加信息到 session 中,而通過向 unset_userdata() 函數中傳遞 session key 可以用來刪除這些信息。例如, 你想要從 session 信息里去掉 'some_name':
$this->session->unset_userdata('some_name');
也可以給這個函數傳一個要刪除項的關聯(lián)數組。
$array_items = array('username' => '', 'email' => '');
$this->session->unset_userdata($array_items);
閃出數據
CodeIgniter 支持 "閃出數據", 或者說Session數據只對下次服務器請求可用, 然后會自動清除。這應該會非常有用,往往應用在信息或狀態(tài)提示中(例如:“記錄2已刪除”)。
注意: 閃出數據變量名以“flash_”開頭,所以在你自己的變量名中要避免使用這個前綴。
要添加閃出數據:
$this->session->set_flashdata('item', 'value');
你也可以使用和 set_userdata() 同樣的方式向 set_flashdata() 傳遞一個數組。
要讀取一個閃出數據變量:
$this->session->flashdata('item');
如果你發(fā)現(xiàn)你需要在一個附加的請求中保留一個閃出數據,你可以使用 keep_flashdata() 這個函數。
$this->session->keep_flashdata('item');
將 Session 數據存入數據庫
由于Session數據數組是附帶一個Session ID保存在用戶cookie里的,你無法驗證它,除非你把session數據存儲在數據庫中。在一些不需要或很少需要安全保護的應用中,session ID 或許并不需要。但如果你的應用需要安全保護,驗證是必須的。Otherwise, an old session could be restored by a user modifying their cookies.
當session 數據在數據庫中可用時,每當從用戶cookie中發(fā)現(xiàn)一個有效的session,一個數據庫查詢就會被執(zhí)行以匹配它。如果 session ID 不相配,session 就會被銷毀。Session ID永遠不會更新,它們只會在一個新的會話創(chuàng)建時生成。
為了存儲session,你必須先創(chuàng)建一個數據表。這是 session 類所需的基本結構(用于MySQL的):
注意: 默認情況下這個表叫做 ci_sessions, 但是你可以給它指定任意名字,只要你更新了 application/config/config.php 文件以確保它包含了你所起的名字。 一旦你創(chuàng)建了數據表,你就可以像下面這樣在config.php文件中啟用數據庫選項:
$config['sess_use_database'] = TRUE;
一旦啟用了,Session類就會在數據庫中存儲session數據。
同時確保你已經在配置文件中指定了數據表名:
$config['sess_table_name'] = 'ci_sessions';
注意: Session類已經內置了清除過期session的垃圾回收機制,因此你不需要編寫你自己的事務來做這個。
銷毀 Session
要清除當前 session:
$this->session->sess_destroy();
注意: 此函數應該是最后被調用的。即使閃出變量已不再有效。如果你只想讓某幾項而不是所有項被銷毀,請使用 unset_userdata().
Session 的參數
你可以在application/config/config.php 文件中找到以下的 Session 相關的參數:
參數 | 默認 | 選項 | 描述 |
---|---|---|---|
sess_cookie_name | ci_session | 無 | 你想要保存 Session Cookie 的名字。 |
sess_expiration | 7200 | 無 | session 持續(xù)的秒數。默認是2個小時(7200秒)。如果將這個數值設為: 0,就可以得到 永久 session。 |
sess_expire_on_close | FALSE | TRUE/FALSE (boolean) | 這個選項決定當瀏覽器窗口關閉時是否自動使session過期。 |
sess_encrypt_cookie | FALSE | TRUE/FALSE (布爾值boolean) | 是否對 session 數據加密. |
sess_use_database | FALSE | TRUE/FALSE (布爾值boolean) | 是否將 session 數據存放入數據庫中。在開啟這個選項前,你要先創(chuàng)建一個數據庫表。 |
sess_table_name | ci_sessions | 任何有效的 SQL 表名 | session 數據庫表的名字。 |
sess_time_to_update | 300 | 時間以秒計算 | 這個選項控制 session 類多久會產生一個新的session 和 session id。 |
sess_match_ip | FALSE | TRUE/FALSE (布爾值boolean) | 是否通過用戶的IP地址來讀取 session 的數據。 注意 ,有些網絡運行商 ISPs 會動態(tài)的改變IP, 所以將這個選項設為 FALSE, 才有可能得到永久的 session。 |
sess_match_useragent | TRUE | TRUE/FALSE (布爾值boolean) | 是否要按照對應的 User Agent 來讀取 session 數據。 |
?