99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

CodeIgniter Session 類

2018-07-21 15:40 更新

Session 類

Session(會(huì)話)類可以讓你保持一個(gè)用戶的 "狀態(tài)" ,并跟蹤他在瀏覽你的網(wǎng)站時(shí)的活動(dòng)。

CodeIgniter 自帶了幾個(gè)存儲(chǔ) session 的驅(qū)動(dòng):

  • 文件(默認(rèn)的,基于文件系統(tǒng))
  • 數(shù)據(jù)庫(kù)
  • Redis
  • Memcached

另外,你也可以基于其他的存儲(chǔ)機(jī)制來(lái)創(chuàng)建你自己的自定義 session 存儲(chǔ)驅(qū)動(dòng), 使用自定義的驅(qū)動(dòng),同樣也可以使用 Session 類提供的那些功能。

[TOC=2.3]

使用 Session 類

初始化 Session 類

Session 通常會(huì)在每個(gè)頁(yè)面載入的時(shí)候全局運(yùn)行,所以 Session 類必須首先被初始化。 您可以在 控制器 的構(gòu)造函數(shù)中初始化它, 也可以在系統(tǒng)中 自動(dòng)加載。Session 類基本上都是在后臺(tái)運(yùn)行, 你不會(huì)注意到。所以當(dāng)初始化 session 之后,系統(tǒng)會(huì)自動(dòng)讀取、創(chuàng)建和更新 session 數(shù)據(jù) 。

要手動(dòng)初始化 Session 類,你可以在控制器的構(gòu)造函數(shù)中使用 $this->load->library() 方法:

$this->load->library('session');

初始化之后,就可以使用下面的方法來(lái)訪問(wèn) Session 對(duì)象了:

$this->session

重要

由于 加載類 是在 CodeIgniter 的控制器基類中實(shí)例化的, 所以如果要在你的控制器構(gòu)造函數(shù)中加載類庫(kù)的話,確保先調(diào)用 parent::__construct()方法。

Session 是如何工作的?

當(dāng)頁(yè)面載入后,Session 類就會(huì)檢查用戶的 cookie 中是否存在有效的 session 數(shù)據(jù)。 如果 session 數(shù)據(jù)不存在(或者與服務(wù)端不匹配,或者已經(jīng)過(guò)期), 那么就會(huì)創(chuàng)建一個(gè)新的 session 并保存起來(lái)。

如果 session 數(shù)據(jù)存在并且有效,那么就會(huì)更新 session 的信息。 根據(jù)你的配置,每一次更新都會(huì)生成一個(gè)新的 Session ID 。

有一點(diǎn)非常重要,你需要了解一下,Session 類一旦被初始化,它就會(huì)自動(dòng)運(yùn)行。 上面所說(shuō)的那些,你完全不用做任何操作。正如接下來(lái)你將看到的那樣, 你可以正常的使用 session 數(shù)據(jù),至于讀、寫和更新 session 的操作都是自動(dòng)完成的。

注解

在 CLI 模式下,Session 類將自動(dòng)關(guān)閉,這種做法完全是基于 HTTP 協(xié)議的。

關(guān)于并發(fā)的注意事項(xiàng)

如果你開(kāi)發(fā)的網(wǎng)站并不是大量的使用 AJAX 技術(shù),那么你可以跳過(guò)這一節(jié)。 如果你的網(wǎng)站是大量的使用了 AJAX,并且遇到了性能問(wèn)題,那么下面的注意事項(xiàng), 可能正是你需要的。

在 CodeIgniter 之前的版本中,Session 類并沒(méi)有實(shí)現(xiàn)鎖機(jī)制,這也就意味著, 兩個(gè) HTTP 請(qǐng)求可能會(huì)同時(shí)使用同一個(gè) session 。說(shuō)的更專業(yè)點(diǎn)就是, 請(qǐng)求是非阻塞的。(requests were non-blocking)

在處理 session 時(shí)使用非阻塞的請(qǐng)求同樣意味著不安全,因?yàn)樵谝粋€(gè)請(qǐng)求中修改 session 數(shù)據(jù)(或重新生成 Session ID)會(huì)對(duì)并發(fā)的第二個(gè)請(qǐng)求造成影響。這是導(dǎo)致很多問(wèn)題的根源, 同時(shí)也是為什么 CodeIgniter 3.0 對(duì) Session 類完全重寫的原因。

那么為什么要告訴你這些呢?這是因?yàn)樵谀悴檎倚阅軉?wèn)題的原因時(shí), 可能會(huì)發(fā)現(xiàn)加鎖機(jī)制正是導(dǎo)致性能問(wèn)題的罪魁禍?zhǔn)祝虼司拖胫绾稳サ翩i ...

請(qǐng)不要這樣做! 去掉加鎖機(jī)制是完全錯(cuò)誤的,它會(huì)給你帶來(lái)更多的問(wèn)題!

鎖并不是問(wèn)題,它是一種解決方案。你的問(wèn)題是當(dāng) session 已經(jīng)處理完畢不再需要時(shí), 你還將 session 保持是打開(kāi)的狀態(tài)。所以,你需要做的其實(shí)是,當(dāng)結(jié)束當(dāng)前請(qǐng)求時(shí), 將不再需要的 session 關(guān)閉掉。

簡(jiǎn)單來(lái)說(shuō)就是:當(dāng)你不再需要使用某個(gè) session 變量時(shí),就使用 session_write_close() 方法來(lái)關(guān)閉它。

什么是 Session 數(shù)據(jù)?

Session 數(shù)據(jù)是個(gè)簡(jiǎn)單的數(shù)組,帶有一個(gè)特定的 session ID (cookie)。

如果你之前在 PHP 里使用過(guò) session ,你應(yīng)該對(duì) PHP 的 $_SESSION 全局變量 很熟悉(如果沒(méi)有,請(qǐng)閱讀下鏈接中的內(nèi)容)。

CodeIgniter 使用了相同的方式來(lái)訪問(wèn) session 數(shù)據(jù),同時(shí)使用了 PHP 自帶的 session 處理機(jī)制, 使用 session 數(shù)據(jù)和操作 $_SESSION 數(shù)組一樣簡(jiǎn)單(包括讀取,設(shè)置,取消設(shè)置)。

另外,CodeIgniter 還提供了兩種特殊類型的 session 數(shù)據(jù):flashdata 和 tempdata ,在下面將有介紹。

注解

在之前的 CodeIgniter 版本中,常規(guī)的 session 數(shù)據(jù)被稱之為 'userdata' ,當(dāng)文檔中出現(xiàn)這個(gè)詞時(shí)請(qǐng)記住這一點(diǎn)。 大部分都是用于解釋自定義 'userdata' 方法是如何工作的。

獲取 Session 數(shù)據(jù)

session 數(shù)組中的任何信息都可以通過(guò) $_SESSION 全局變量獲取:

$_SESSION['item']

或使用下面的方法(magic getter):

$this->session->item

同時(shí),為了和之前的版本兼容,也可以使用 userdata() 方法:

$this->session->userdata('item');

其中,item 是你想獲取的數(shù)組的鍵值。例如,將 'name' 鍵值對(duì)應(yīng)的項(xiàng)賦值給 $name 變量, 你可以這樣:

$name = $_SESSION['name'];

// or:

$name = $this->session->name

// or:

$name = $this->session->userdata('name');

注解

如果你訪問(wèn)的項(xiàng)不存在,userdata() 方法返回 NULL 。

如果你想獲取所有已存在的 userdata ,你可以忽略 item 參數(shù):

$_SESSION

// or:

$this->session->userdata();

添加 Session 數(shù)據(jù)

假設(shè)某個(gè)用戶訪問(wèn)你的網(wǎng)站,當(dāng)他完成認(rèn)證之后,你可以將他的用戶名和 email 地址添加到 session 中, 這樣當(dāng)你需要的時(shí)候你就可以直接訪問(wèn)這些數(shù)據(jù),而無(wú)法查詢數(shù)據(jù)庫(kù)了。

你可以簡(jiǎn)單的將數(shù)據(jù)賦值給 $_SESSION 數(shù)組,或賦值給 $this->session 的某個(gè)屬性。

同時(shí),老版本中的通過(guò) "userdata" 來(lái)賦值的方法也還可以用,只不過(guò)是需要傳遞一個(gè)包含你的數(shù)據(jù)的數(shù)組 給 set_userdata() 方法:

$this->session->set_userdata($array);

其中,$array 是包含新增數(shù)據(jù)的一個(gè)關(guān)聯(lián)數(shù)組,下面是個(gè)例子:

$newdata = array(
    'username'  => 'johndoe',
    'email'     => 'johndoe@some-site.com',
    'logged_in' => TRUE
);

$this->session->set_userdata($newdata);

如果你想一次只添加一個(gè)值,set_userdata() 也支持這種語(yǔ)法:

$this->session->set_userdata('some_name', 'some_value');

如果你想檢查某個(gè) session 值是否存在,可以使用 isset():

// returns FALSE if the 'some_name' item doesn't exist or is NULL,
// TRUE otherwise:
isset($_SESSION['some_name'])

或者,你也可以使用 has_userdata():

$this->session->has_userdata('some_name');

刪除 Session 數(shù)據(jù)

和其他的變量一樣,可以使用 unset() 方法來(lái)刪除 $_SESSION 數(shù)組中的某個(gè)值:

unset($_SESSION['some_name']);

// or multiple values:

unset(
    $_SESSION['some_name'],
    $_SESSION['another_name']
);

同時(shí),正如 set_userdata() 方法可用于向 session 中添加數(shù)據(jù),unset_userdata() 方法可用于刪除指定鍵值的數(shù)據(jù)。例如,如果你想從你的 session 數(shù)組中刪除 'some_name':

$this->session->unset_userdata('some_name');

這個(gè)方法也可以使用一個(gè)數(shù)組來(lái)同時(shí)刪除多個(gè)值:

$array_items = array('username', 'email');

$this->session->unset_userdata($array_items);

注解

在 CodeIgniter 之前的版本中,unset_userdata() 方法接受一個(gè)關(guān)聯(lián)數(shù)組, 包含 key => 'dummy value' 這樣的鍵值對(duì),這種方式不再支持。

Flashdata

CodeIgniter 支持 "flashdata" ,它指的是一種只對(duì)下一次請(qǐng)求有效的 session 數(shù)據(jù), 之后將會(huì)自動(dòng)被清除。

這用于一次性的信息時(shí)特別有用,例如錯(cuò)誤或狀態(tài)信息(諸如 "第二條記錄刪除成功" 這樣的信息)。

要注意的是,flashdata 就是常規(guī)的 session 變量,只不過(guò)以特殊的方式保存在 '__ci_vars' 鍵下 (警告:請(qǐng)不要亂動(dòng)這個(gè)值)。

將已有的值標(biāo)記為 "flashdata":

$this->session->mark_as_flash('item');

通過(guò)傳一個(gè)數(shù)組,同時(shí)標(biāo)記多個(gè)值為 flashdata:

$this->session->mark_as_flash(array('item', 'item2'));

使用下面的方法來(lái)添加 flashdata:

$_SESSION['item'] = 'value';
$this->session->mark_as_flash('item');

或者,也可以使用 set_flashdata() 方法:

$this->session->set_flashdata('item', 'value');

你還可以傳一個(gè)數(shù)組給 set_flashdata() 方法,和 set_userdata() 方法一樣。

讀取 flashdata 和讀取常規(guī)的 session 數(shù)據(jù)一樣,通過(guò) $_SESSION 數(shù)組:

$_SESSION['item']

重要

userdata() 方法不會(huì)返回 flashdata 數(shù)據(jù)。

如果你要確保你讀取的就是 "flashdata" 數(shù)據(jù),而不是其他類型的數(shù)據(jù),可以使用 flashdata() 方法:

$this->session->flashdata('item');

或者不傳參數(shù),直接返回所有的 flashdata 數(shù)組:

$this->session->flashdata();

注解

如果讀取的值不存在,flashdata() 方法返回 NULL 。

如果你需要在另一個(gè)請(qǐng)求中還繼續(xù)保持 flashdata 變量,你可以使用 keep_flashdata() 方法。 可以傳一個(gè)值,或包含多個(gè)值的一個(gè)數(shù)組。

$this->session->keep_flashdata('item');
$this->session->keep_flashdata(array('item1', 'item2', 'item3'));

Tempdata

CodeIgniter 還支持 "tempdata" ,它指的是一種帶有有效時(shí)間的 session 數(shù)據(jù), 當(dāng)它的有效時(shí)間已過(guò)期,或在有效時(shí)間內(nèi)被刪除,都會(huì)自動(dòng)被清除。

和 flashdata 一樣, tempdata 也是常規(guī)的 session 變量,只不過(guò)以特殊的方式保存在 '__ci_vars' 鍵下 (再次警告:請(qǐng)不要亂動(dòng)這個(gè)值)。

將已有的值標(biāo)記為 "tempdata" ,只需簡(jiǎn)單的將要標(biāo)記的鍵值和過(guò)期時(shí)間(單位為秒)傳給 mark_as_temp() 方法即可:

// 'item' will be erased after 300 seconds
$this->session->mark_as_temp('item', 300);

你也可以同時(shí)標(biāo)記多個(gè)值為 tempdata ,有下面兩種不同的方式, 這取決于你是否要將所有的值都設(shè)置成相同的過(guò)期時(shí)間:

// Both 'item' and 'item2' will expire after 300 seconds
$this->session->mark_as_temp(array('item', 'item2'), 300);

// 'item' will be erased after 300 seconds, while 'item2'
// will do so after only 240 seconds
$this->session->mark_as_temp(array(
    'item'  => 300,
    'item2' => 240
));

使用下面的方法來(lái)添加 tempdata:

$_SESSION['item'] = 'value';
$this->session->mark_as_temp('item', 300); // Expire in 5 minutes

或者,也可以使用 set_tempdata() 方法:

$this->session->set_tempdata('item', 'value', 300);

你還可以傳一個(gè)數(shù)組給 set_tempdata() 方法:

$tempdata = array('newuser' => TRUE, 'message' => 'Thanks for joining!');

$this->session->set_tempdata($tempdata, NULL, $expire);

注解

如果沒(méi)有設(shè)置 expiration 參數(shù),或者設(shè)置為 0 ,將默認(rèn)使用 300秒(5分鐘)作為生存時(shí)間(time-to-live)。

要讀取 tempdata 數(shù)據(jù),你可以再一次通過(guò) $_SESSION 數(shù)組:

$_SESSION['item']

重要

userdata() 方法不會(huì)返回 tempdata 數(shù)據(jù)。

如果你要確保你讀取的就是 "tempdata" 數(shù)據(jù),而不是其他類型的數(shù)據(jù),可以使用 tempdata() 方法:

$this->session->tempdata('item');

或者不傳參數(shù),直接返回所有的 tempdata 數(shù)組:

$this->session->tempdata();

注解

如果讀取的值不存在,tempdata() 方法返回 NULL 。

如果你需要在某個(gè) tempdata 過(guò)期之前刪除它,你可以直接通過(guò) $_SESSION 數(shù)組來(lái)刪除:

unset($_SESSION['item']);

但是,這不會(huì)刪除這個(gè)值的 tempdata 標(biāo)記(會(huì)在下一次 HTTP 請(qǐng)求時(shí)失效),所以, 如果你打算在相同的請(qǐng)求中重用這個(gè)值,你可以使用unset_tempdata():

$this->session->unset_tempdata('item');

銷毀 Session

要清除當(dāng)前的 session(例如:退出登錄時(shí)),你可以簡(jiǎn)單的使用 PHP 自帶的 session_destroy() 函數(shù)或者 sess_destroy() 方法。 兩種方式效果完全一樣:

session_destroy();

// or

$this->session->sess_destroy();

注解

這必須是同一個(gè)請(qǐng)求中關(guān)于 session 的最后一次操作,所有的 session 數(shù)據(jù)(包括 flashdata 和 tempdata)都被永久性銷毀,銷毀之后,關(guān)于 session 的方法將不可用。

訪問(wèn) session 元數(shù)據(jù)

在之前的 CodeIgniter 版本中,session 數(shù)據(jù)默認(rèn)包含 4 項(xiàng):'session_id' 、 'ip_address' 、 'user_agent' 、 'last_activity' 。

這是由 session 具體的工作方式?jīng)Q定的,但是我們現(xiàn)在的實(shí)現(xiàn)沒(méi)必要這樣做了。 盡管如此,你的應(yīng)用程序可能還依賴于這些值,所以下面提供了訪問(wèn)這些值的替代方法:

  • session_id: session_id()
  • ip_address: $_SERVER['REMOTE_ADDR']
  • user_agent: $this->input->user_agent() (unused by sessions)
  • last_activity: 取決于 session 的存儲(chǔ)方式,沒(méi)有直接的方法,抱歉!

Session 參數(shù)

在 CodeIgniter 中通常所有的東西都是拿來(lái)直接就可以用的,盡管如此,session 對(duì)于所有的程序來(lái)說(shuō), 都是一個(gè)非常敏感的部分,所以必須要小心的配置它。請(qǐng)花點(diǎn)時(shí)間研究下下面所有的選項(xiàng)以及每個(gè)選項(xiàng)的作用。

你可以在你的配置文件 application/config/config.php 中找到下面的關(guān)于 session 的配置參數(shù):

參數(shù) 默認(rèn)值 選項(xiàng) 描述
sess_driver files files/database/redis/memcached/custom 使用的存儲(chǔ) session 的驅(qū)動(dòng)
sess_cookie_name ci_session [A-Za-z_-] characters only session cookie 的名稱
sess_expiration 7200 (2 hours) Time in seconds (integer) 你希望 session 持續(xù)的秒數(shù) 如果你希望 session 不過(guò)期(直到瀏覽器關(guān)閉),將其設(shè)置為 0
sess_save_path NULL None 指定存儲(chǔ)位置,取決于使用的存儲(chǔ) session 的驅(qū)動(dòng)
sess_match_ip FALSE TRUE/FALSE (boolean) 讀取 session cookie 時(shí),是否驗(yàn)證用戶的 IP 地址 注意有些 ISP 會(huì)動(dòng)態(tài)的修改 IP ,所以如果你想要一個(gè)不過(guò)期的 session,將其設(shè)置為 FALSE
sess_time_to_update 300 Time in seconds (integer) 該選項(xiàng)用于控制過(guò)多久將重新生成一個(gè)新 session ID 設(shè)置為 0 將禁用 session ID 的重新生成
sess_regenerate_destroy FALSE TRUE/FALSE (boolean) 當(dāng)自動(dòng)重新生成 session ID 時(shí),是否銷毀老的 session ID 對(duì)應(yīng)的數(shù)據(jù) 如果設(shè)置為 FALSE ,數(shù)據(jù)之后將自動(dòng)被垃圾回收器刪除

注解

如果上面的某個(gè)參數(shù)沒(méi)有配置,Session 類將會(huì)試圖讀取 php.ini 配置文件中的 session 相關(guān)的配置 (例如 'sess_expire_on_close')。但是,請(qǐng)不要依賴于這個(gè)行為,因?yàn)檫@可能會(huì)導(dǎo)致不可預(yù)期的結(jié)果,而且 這也有可能在未來(lái)的版本中修改。請(qǐng)合理的配置每一個(gè)參數(shù)。

除了上面的這些參數(shù)之外,cookie 和 session 原生的驅(qū)動(dòng)還會(huì)公用下面這些 由 輸入類 和 安全類 提供的配置參數(shù)。

參數(shù) 默認(rèn)值 描述
cookie_domain '' session 可用的域
cookie_path / session 可用的路徑
cookie_secure FALSE 是否只在加密連接(HTTPS)時(shí)創(chuàng)建 session cookie

注解

'cookie_httponly' 配置對(duì) session 沒(méi)有影響。出于安全原因,HttpOnly 參數(shù)將一直啟用。 另外,'cookie_prefix' 參數(shù)完全可以忽略。

Session 驅(qū)動(dòng)

正如上面提到的,Session 類自帶了 4 種不同的驅(qū)動(dòng)(或叫做存儲(chǔ)引擎)可供使用:

  • files
  • database
  • redis
  • memcached

默認(rèn)情況下,初始化 session 時(shí)將使用 文件驅(qū)動(dòng) ,因?yàn)檫@是最安全的選擇,可以在所有地方按預(yù)期工作 (幾乎所有的環(huán)境下都有文件系統(tǒng))。

但是,你也可以通過(guò) application/config/config.php 配置文件中的 $config['sess_driver'] 參數(shù)來(lái)使用任何其他的驅(qū)動(dòng)。特別提醒的是,每一種驅(qū)動(dòng)都有它自己的注意事項(xiàng),所以在你選擇之前, 確定你熟悉它們。

另外,如果默認(rèn)提供的這些不能滿足你的需求,你也可以創(chuàng)建和使用 自定義驅(qū)動(dòng) 。

注解

在之前版本的 CodeIgniter 中,只有 "cookie 驅(qū)動(dòng)" 這唯一的一種選擇, 因?yàn)檫@個(gè)我們收到了大量的負(fù)面的反饋。因此,我們吸取了社區(qū)的反饋意見(jiàn),同時(shí)也要提醒你, 因?yàn)樗?strong>不安全,所以已經(jīng)被廢棄了,建議你不要試著通過(guò) 自定義驅(qū)動(dòng) 來(lái)重新實(shí)現(xiàn)它。

文件驅(qū)動(dòng)

文件驅(qū)動(dòng)利用你的文件系統(tǒng)來(lái)存儲(chǔ) session 數(shù)據(jù)。

可以說(shuō),文件驅(qū)動(dòng)和 PHP 自帶的默認(rèn) session 實(shí)現(xiàn)非常類似,但是有一個(gè)很重要的細(xì)節(jié)要注意的是, 實(shí)際上它們的代碼并不相同,而且有一些局限性(以及優(yōu)勢(shì))。

說(shuō)的更具體點(diǎn),它不支持 PHP 的 session.save_path 參數(shù)的 目錄分級(jí)(directory level)和 mode 格式 , 另外為了安全性大多數(shù)的參數(shù)都被硬編碼。只提供了 $config['sess_save_path'] 參數(shù)用于設(shè)置絕對(duì)路徑。

另一個(gè)很重要的事情是,確保存儲(chǔ) session 文件的目錄不能被公開(kāi)訪問(wèn)到或者是共享目錄,確保 只有你 能訪問(wèn)并查看配置的 sess_save_path 目錄中的內(nèi)容。否則,如果任何人都能訪問(wèn), 他們就可以從中竊取到當(dāng)前的 session (這也被稱為 session 固定(session fixation)攻擊)

在類 UNIX 操作系統(tǒng)中,這可以通過(guò)在該目錄上執(zhí)行 chmod 命令,將權(quán)限設(shè)置為 0700 來(lái)實(shí)現(xiàn), 這樣就可以只允許目錄的所有者執(zhí)行讀取和寫入操作。但是要注意的是,腳本的執(zhí)行者通常不是你自己, 而是類似于 'www-data' 這樣的用戶,所以只設(shè)置權(quán)限可能會(huì)破壞你的程序。

根據(jù)你的環(huán)境,你應(yīng)該像下面這樣來(lái)操作。

mkdir /<path to your application directory>/sessions/
chmod 0700 /<path to your application directory>/sessions/
chown www-data /<path to your application directory>/sessions/
小提示

有些人可能會(huì)選擇使用其他的 session 驅(qū)動(dòng),他們認(rèn)為文件存儲(chǔ)通常比較慢。其實(shí)這并不總是對(duì)的。

執(zhí)行一些簡(jiǎn)單的測(cè)試可能會(huì)讓你真的相信 SQL 數(shù)據(jù)庫(kù)更快一點(diǎn),但是在 99% 的情況下,這只是當(dāng)你的 session 并發(fā)非常少的時(shí)候是對(duì)的。當(dāng) session 的并發(fā)數(shù)越來(lái)越大,服務(wù)器的負(fù)載越來(lái)越高, 這時(shí)就不一樣了,文件系統(tǒng)將會(huì)勝過(guò)幾乎所有的關(guān)系型數(shù)據(jù)庫(kù)。

另外,如果性能是你唯一關(guān)心的,你可以看下 tmpfs (注意:外部資源),它可以讓你的 session 非???。

數(shù)據(jù)庫(kù)驅(qū)動(dòng)

數(shù)據(jù)庫(kù)驅(qū)動(dòng)使用諸如 MySQL 或 PostgreSQL 這樣的關(guān)系型數(shù)據(jù)庫(kù)來(lái)存儲(chǔ) session , 這是一個(gè)非常常見(jiàn)的選擇,因?yàn)樗梢宰岄_(kāi)發(fā)者非常方便的訪問(wèn)應(yīng)用中的 session 數(shù)據(jù), 因?yàn)樗皇悄愕臄?shù)據(jù)庫(kù)中的一個(gè)表而已。

但是,還是有幾點(diǎn)要求必須滿足:

  • 只有設(shè)置為 default 的數(shù)據(jù)庫(kù)連接可以使用(或者在控制器中使用 $this->db 來(lái)訪問(wèn)的連接)
  • 你必須啟用 查詢構(gòu)造器
  • 不能使用持久連接
  • 使用的數(shù)據(jù)庫(kù)連接不能啟用 cache_on 參數(shù)

為了使用數(shù)據(jù)庫(kù)驅(qū)動(dòng),你還需要?jiǎng)?chuàng)建一個(gè)我們剛剛已經(jīng)提到的數(shù)據(jù)表,然后將 $config['sess_save_path'] 參數(shù)設(shè)置為表名。例如,如果你想使用 'ci_sessions' 這個(gè)表名,你可以這樣:

$config['sess_driver'] = 'database';
$config['sess_save_path'] = 'ci_sessions';

注解

如果你從 CodeIgniter 之前的版本中升級(jí)過(guò)來(lái)的,并且沒(méi)有配置 'sess_save_path' 參數(shù), Session 類將查找并使用老的 'sess_table_name' 參數(shù)替代。請(qǐng)不要依賴這個(gè)行為, 因?yàn)樗赡軙?huì)在以后的版本中移除。

然后,新建數(shù)據(jù)表 。

對(duì)于 MySQL:

CREATE TABLE IF NOT EXISTS `ci_sessions` (
    `id` varchar(40) NOT NULL,
    `ip_address` varchar(45) NOT NULL,
    `timestamp` int(10) unsigned DEFAULT 0 NOT NULL,
    `data` blob NOT NULL,
    PRIMARY KEY (id),
    KEY `ci_sessions_timestamp` (`timestamp`)
);

對(duì)于 PostgreSQL:

CREATE TABLE "ci_sessions" (
    "id" varchar(40) NOT NULL,
    "ip_address" varchar(45) NOT NULL,
    "timestamp" bigint DEFAULT 0 NOT NULL,
    "data" text DEFAULT '' NOT NULL,
    PRIMARY KEY ("id")
);

CREATE INDEX "ci_sessions_timestamp" ON "ci_sessions" ("timestamp");

如果你想開(kāi)啟 sess_match_ip 參數(shù),你還應(yīng)該在新建表之后進(jìn)行如下操作:

// Works both on MySQL and PostgreSQL
ALTER TABLE ci_sessions ADD CONSTRAINT ci_sessions_id_ip UNIQUE (id, ip_address);

重要

只有 MySQL 和 PostgreSQL 數(shù)據(jù)庫(kù)是被正式支持的,因?yàn)槠渌麛?shù)據(jù)庫(kù)平臺(tái)都缺乏合適的鎖機(jī)制。 在沒(méi)鎖的情況下使用 session 可能會(huì)導(dǎo)致大量的問(wèn)題,特別是使用了大量的 AJAX , 所以我們并不打算支持這種情況。如果你遇到了性能問(wèn)題,請(qǐng)你在完成 session 數(shù)據(jù)的處理之后, 調(diào)用session_write_close() 方法。

Redis 驅(qū)動(dòng)

注解

由于 Redis 沒(méi)有鎖機(jī)制,這個(gè)驅(qū)動(dòng)的鎖是通過(guò)一個(gè)保持 300 秒的值來(lái)模擬的 (emulated by a separate value that is kept for up to 300 seconds)。

Redis 是一種存儲(chǔ)引擎,通常用于緩存,并由于他的高性能而流行起來(lái),這可能也正是你使用 Redis 驅(qū)動(dòng)的原因。

缺點(diǎn)是它并不像關(guān)系型數(shù)據(jù)庫(kù)那樣普遍,需要你的系統(tǒng)中安裝了 phpredis 這個(gè) PHP 擴(kuò)展,它并不是 PHP 程序自帶的。 可能的情況是,你使用 Redis 驅(qū)動(dòng)的原因是你已經(jīng)非常熟悉 Redis 了并且你使用它還有其他的目的。

和文件驅(qū)動(dòng)和數(shù)據(jù)庫(kù)驅(qū)動(dòng)一樣,你必須通過(guò) $config['sess_save_path'] 參數(shù)來(lái)配置存儲(chǔ) session 的位置。 這里的格式有些不同,同時(shí)也要復(fù)雜一點(diǎn),這在 phpredis 擴(kuò)展的 README 文件中有很好的解釋,鏈接如下:

https://github.com/phpredis/phpredis#php-session-handler

警告

CodeIgniter 的 Session 類并沒(méi)有真的用到 'redis' 的 session.save_handler , 只是 采用了它的路徑的格式而已。

最常見(jiàn)的情況是,一個(gè)簡(jiǎn)單 host:port 對(duì)就可以了:

$config['sess_driver'] = 'redis';
$config['sess_save_path'] = 'tcp://localhost:6379';

Memcached 驅(qū)動(dòng)

注解

由于 Memcache 沒(méi)有鎖機(jī)制,這個(gè)驅(qū)動(dòng)的鎖是通過(guò)一個(gè)保持 300 秒的值來(lái)模擬的 (emulated by a separate value that is kept for up to 300 seconds)。

Memcached 驅(qū)動(dòng)和 Redis 驅(qū)動(dòng)非常相似,除了它的可用性可能要好點(diǎn),因?yàn)?PHP 的 Memcached 擴(kuò)展已經(jīng)通過(guò) PECL 發(fā)布了,并且在某些 Linux 發(fā)行版本中, 可以非常方便的安裝它。

除了這一點(diǎn),以及排除任何對(duì) Redis 的偏見(jiàn),關(guān)于 Memcached 要說(shuō)的真的沒(méi)什么區(qū)別, 它也是一款通常用于緩存的產(chǎn)品,而且以它的速度而聞名。

不過(guò),值得注意的是,使用 Memcached 設(shè)置 X 的過(guò)期時(shí)間為 Y 秒,它只能保證 X 會(huì)在 Y 秒過(guò)后被刪除 (但不會(huì)早于這個(gè)時(shí)間)。這個(gè)是非常少見(jiàn)的,但是應(yīng)該注意一下,因?yàn)樗赡軙?huì)導(dǎo)致 session 的丟失。

$config['sess_save_path'] 參數(shù)的格式相當(dāng)簡(jiǎn)單,使用 host:port 對(duì)即可:

$config['sess_driver'] = 'memcached';
$config['sess_save_path'] = 'localhost:11211';
小提示

也可以使用一個(gè)可選的 權(quán)重 參數(shù)來(lái)支持多服務(wù)器的配置,權(quán)重參數(shù)使用冒號(hào)分割(:weight), 但是我們并沒(méi)有測(cè)試這是絕對(duì)可靠的。

如果你想體驗(yàn)這個(gè)特性(風(fēng)險(xiǎn)自負(fù)),只需簡(jiǎn)單的將多個(gè)服務(wù)器使用逗號(hào)分隔:

// localhost will be given higher priority (5) here,
// compared to 192.0.2.1 with a weight of 1.
$config['sess_save_path'] = 'localhost:11211:5,192.0.2.1:11211:1';

自定義驅(qū)動(dòng)

你也可以創(chuàng)建你自己的自定義 session 驅(qū)動(dòng),但是要記住的是,這通常來(lái)說(shuō)都不是那么簡(jiǎn)單, 因?yàn)樾枰玫胶芏嘀R(shí)來(lái)正確實(shí)現(xiàn)它。

你不僅要知道 session 一般的工作原理,而且要知道它在 PHP 中是如何實(shí)現(xiàn)的, 還要知道它的內(nèi)部存儲(chǔ)機(jī)制是如何工作的,如何去處理并發(fā),如何去避免死鎖(不是通過(guò)去掉鎖機(jī)制), 以及最后一點(diǎn)但也是很重要的一點(diǎn),如何去處理潛在的安全問(wèn)題。

總的來(lái)說(shuō),如果你不知道怎么在原生的 PHP 中實(shí)現(xiàn)這些,那么你也不應(yīng)該在 CodeIgniter 中嘗試實(shí)現(xiàn)它。 我已經(jīng)警告過(guò)你了。

如果你只想給你的 session 添加一些額外的功能,你只要擴(kuò)展 Session 基類就可以了,這要容易的多。 要學(xué)習(xí)如何實(shí)現(xiàn)這點(diǎn),請(qǐng)閱讀 創(chuàng)建你的類庫(kù) 這一節(jié)。

言歸正傳,當(dāng)你為 CodeIgniter 創(chuàng)建 session 驅(qū)動(dòng)時(shí),有三條規(guī)則你必須遵循:

  • 將你的驅(qū)動(dòng)文件放在 application/libraries/Session/drivers/ 目錄下,并遵循 Session 類所使用的命名規(guī)范。

    例如,如果你想創(chuàng)建一個(gè)名為 'dummy' 的驅(qū)動(dòng),那么你需要?jiǎng)?chuàng)建一個(gè)名為 Session_dummy_driver 的類, 并將其放在application/libraries/Session/drivers/Session_dummy_driver.php 文件中。

  • 擴(kuò)展 CI_Session_driver 類。

    這只是一個(gè)擁有幾個(gè)內(nèi)部輔助方法的基本類,同樣可以和其他類庫(kù)一樣被擴(kuò)展。如果你真的需要這樣做, 我們并不打算在這里多做解釋,因?yàn)槿绻阒廊绾卧?CI 中擴(kuò)展或覆寫類,那么你已經(jīng)知道這樣做的方法了。 如果你還不知道,那么可能你根本就不應(yīng)該這樣做。

  • 實(shí)現(xiàn) SessionHandlerInterface 接口。

    注解

    你可能已經(jīng)注意到 SessionHandlerInterface 接口已經(jīng)在 PHP 5.4.0 之后的版本中提供了。 CodeIgniter 會(huì)在你運(yùn)行老版本的 PHP 時(shí)自動(dòng)聲明這個(gè)接口。

    參考連接中的內(nèi)容,了解為什么以及如何實(shí)現(xiàn)。

所以,使用我們上面的 'dummy' 驅(qū)動(dòng)的例子,你可能會(huì)寫如下代碼:

// application/libraries/Session/drivers/Session_dummy_driver.php:

class CI_Session_dummy_driver extends CI_Session_driver implements SessionHandlerInterface
{

    public function __construct(&$params)
    {
        // DO NOT forget this
        parent::__construct($params);

        // Configuration & other initializations
    }

    public function open($save_path, $name)
    {
        // Initialize storage mechanism (connection)
    }

    public function read($session_id)
    {
        // Read session data (if exists), acquire locks
    }

    public function write($session_id, $session_data)
    {
        // Create / update session data (it might not exist!)
    }

    public function close()
    {
        // Free locks, close connections / streams / etc.
    }

    public function destroy($session_id)
    {
        // Call close() method & destroy data for current session (order may differ)
    }

    public function gc($maxlifetime)
    {
        // Erase data for expired sessions
    }

}

如果一切順利,現(xiàn)在你就可以將 sess_driver 參數(shù)設(shè)置為 'dummy' ,來(lái)使用你自定義的驅(qū)動(dòng)。恭喜你!

類參考

classCI_Session

userdata([$key = NULL])

參數(shù):

  • $key (mixed) -- Session item key or NULL

返回: Value of the specified item key, or an array of all userdata

返回類型: mixed

從 $_SESSION 數(shù)組中獲取指定的項(xiàng)。如果沒(méi)有指定參數(shù),返回所有 "userdata" 的數(shù)組。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。 你可以直接使用 $_SESSION 替代它。

all_userdata()

返回: An array of all userdata
返回類型: array

返回所有 "userdata" 的數(shù)組。

注解

該方法已廢棄,使用不帶參數(shù)的 userdata() 方法來(lái)代替。

&get_userdata()

返回: A reference to $_SESSION
返回類型: array

返回一個(gè) $_SESSION 數(shù)組的引用。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。

has_userdata($key)

參數(shù):

  • $key (string) -- Session item key

返回: TRUE if the specified key exists, FALSE if not

返回類型: bool

檢查 $_SESSION 數(shù)組中是否存在某項(xiàng)。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。 它只是 isset($_SESSION[$key]) 的一個(gè)別名,請(qǐng)使用這個(gè)來(lái)替代它。

set_userdata($data[, $value = NULL])

參數(shù):

  • $data (mixed) -- An array of key/value pairs to set as session data, or the key for a single item
  • $value (mixed) -- The value to set for a specific session item, if $data is a key

返回類型: void

將數(shù)據(jù)賦值給 $_SESSION 全局變量。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。

unset_userdata($key)

參數(shù):

  • $key (mixed) -- Key for the session data item to unset, or an array of multiple keys

返回類型: void

從 $_SESSION 全局變量中刪除某個(gè)值。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。 它只是 unset($_SESSION[$key]) 的一個(gè)別名,請(qǐng)使用這個(gè)來(lái)替代它。

mark_as_flash($key)

參數(shù):

  • $key (mixed) -- Key to mark as flashdata, or an array of multiple keys

返回: TRUE on success, FALSE on failure

返回類型: bool

將 $_SESSION 數(shù)組中的一項(xiàng)(或多項(xiàng))標(biāo)記為 "flashdata" 。

get_flash_keys()

返回: Array containing the keys of all "flashdata" items.
返回類型: array

獲取 $_SESSION 數(shù)組中所有標(biāo)記為 "flashdata" 的一個(gè)列表。

umark_flash($key)

參數(shù):

  • $key (mixed) -- Key to be un-marked as flashdata, or an array of multiple keys

返回類型: void

將 $_SESSION 數(shù)組中的一項(xiàng)(或多項(xiàng))移除 "flashdata" 標(biāo)記。

flashdata([$key = NULL])

參數(shù):

  • $key (mixed) -- Flashdata item key or NULL

返回: Value of the specified item key, or an array of all flashdata

返回類型: mixed

從 $_SESSION 數(shù)組中獲取某個(gè)標(biāo)記為 "flashdata" 的指定項(xiàng)。 如果沒(méi)有指定參數(shù),返回所有 "flashdata" 的數(shù)組。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。 你可以直接使用 $_SESSION 替代它。

keep_flashdata($key)

參數(shù):

  • $key (mixed) -- Flashdata key to keep, or an array of multiple keys

返回: TRUE on success, FALSE on failure

返回類型: bool

將某個(gè)指定的 "flashdata" 設(shè)置為在下一次請(qǐng)求中仍然保持有效。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。 它只是 mark_as_flash() 方法的一個(gè)別名。

set_flashdata($data[, $value = NULL])

參數(shù):

  • $data (mixed) -- An array of key/value pairs to set as flashdata, or the key for a single item
  • $value (mixed) -- The value to set for a specific session item, if $data is a key

返回類型: void

將數(shù)據(jù)賦值給 $_SESSION 全局變量,并標(biāo)記為 "flashdata" 。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。

mark_as_temp($key[, $ttl = 300])

參數(shù):

  • $key (mixed) -- Key to mark as tempdata, or an array of multiple keys
  • $ttl (int) -- Time-to-live value for the tempdata, in seconds

返回: TRUE on success, FALSE on failure

返回類型: bool

將 $_SESSION 數(shù)組中的一項(xiàng)(或多項(xiàng))標(biāo)記為 "tempdata" 。

get_temp_keys()

返回: Array containing the keys of all "tempdata" items.
返回類型: array

獲取 $_SESSION 數(shù)組中所有標(biāo)記為 "tempdata" 的一個(gè)列表。

umark_temp($key)

參數(shù):

  • $key (mixed) -- Key to be un-marked as tempdata, or an array of multiple keys

返回類型: void

將 $_SESSION 數(shù)組中的一項(xiàng)(或多項(xiàng))移除 "tempdata" 標(biāo)記。

tempdata([$key = NULL])

參數(shù):

  • $key (mixed) -- Tempdata item key or NULL

返回: Value of the specified item key, or an array of all tempdata

返回類型: mixed

從 $_SESSION 數(shù)組中獲取某個(gè)標(biāo)記為 "tempdata" 的指定項(xiàng)。 如果沒(méi)有指定參數(shù),返回所有 "tempdata" 的數(shù)組。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。 你可以直接使用 $_SESSION 替代它。

set_tempdata($data[, $value = NULL])

參數(shù):

  • $data (mixed) -- An array of key/value pairs to set as tempdata, or the key for a single item
  • $value (mixed) -- The value to set for a specific session item, if $data is a key
  • $ttl (int) -- Time-to-live value for the tempdata item(s), in seconds

返回類型: void

將數(shù)據(jù)賦值給 $_SESSION 全局變量,并標(biāo)記為 "tempdata" 。

注解

這是個(gè)遺留方法,只是為了和老的應(yīng)用程序向前兼容而保留。

sess_regenerate([$destroy = FALSE])

參數(shù):

  • $destroy (bool) -- Whether to destroy session data

返回類型: void

重新生成 session ID ,$destroy 參數(shù)可選,用于銷毀當(dāng)前的 session 數(shù)據(jù)。

注解

該方法只是 PHP 原生的 session_regenerate_id() 函數(shù)的一個(gè)別名而已。

sess_destroy()

返回類型: void

銷毀當(dāng)前 session 。

注解

這個(gè)方法必須在處理 session 相關(guān)的操作的最后調(diào)用。 如果調(diào)用這個(gè)方法,所有的 session 數(shù)據(jù)都會(huì)丟失。

注解

該方法只是 PHP 原生的 session_destroy() 函數(shù)的一個(gè)別名而已。

__get($key)

參數(shù):

  • $key (string) -- Session item key

返回: The requested session data item, or NULL if it doesn't exist

返回類型: mixed

魔術(shù)方法,根據(jù)你的喜好,使用 $this->session->item 這種方式來(lái)替代 $_SESSION['item'] 。

如果你訪問(wèn) $this->session->session_id 它也會(huì)調(diào)用 session_id() 方法來(lái)返回 session ID 。

__set($key, $value)

參數(shù):

  • $key (string) -- Session item key
  • $value (mixed) -- Value to assign to the session item key

返回: void

魔術(shù)方法,直接賦值給 $this->session 屬性,以此來(lái)替代賦值給 $_SESSION 數(shù)組:

$this->session->foo = 'bar';

// Results in:
// $_SESSION['foo'] = 'bar';
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)