CodeIgniter4 Session 類

2020-08-14 15:57 更新

Session 類允許你維護(hù)用戶的 “狀態(tài)” 并跟蹤他們?cè)跒g覽你的網(wǎng)站時(shí)的活動(dòng)。

CodeIgniter 有一些用于會(huì)話(session)儲(chǔ)存的驅(qū)動(dòng)程序,你可以在目錄的最后部分中看到它們:

使用 Session 類

初始化會(huì)話

會(huì)話通常會(huì)在每次加載頁(yè)面時(shí)在全局范圍內(nèi)運(yùn)行,因此應(yīng)該恰當(dāng)?shù)爻跏蓟?Session 類。

訪問并初始化會(huì)話:

$session = \Config\Services::session($config);

$config 參數(shù)是可選的,它是你的應(yīng)用程序配置。如果未提供,服務(wù)將會(huì)使用你的默認(rèn)配置。

初始化成功后,可以用以下方式使用 Session 庫(kù)對(duì)象:

$session

或者,你可以使用使用默認(rèn)配置的 helper 方法,這個(gè)版本閱讀起來會(huì)更友好一些,但是不能配置任何配置選項(xiàng)

$session = session();

Session 是怎樣工作的?

加載頁(yè)面后,Session 類將檢查用戶的瀏覽器是否發(fā)送了有效的會(huì)話 cookie。如果會(huì)話 Cookie 不存在 (或者如果它不匹配一個(gè)存儲(chǔ)在服務(wù)器上的會(huì)話ID或已過期), 新會(huì)話將被創(chuàng)建和保存。

如果確實(shí)存在有效的會(huì)話,則其信息將被更新。對(duì)于每次更新,如果配置了會(huì)話 ID ,則可以對(duì)其進(jìn)行重新生成。

對(duì)你來說很重要的一點(diǎn)是,一旦初始化,Session 類就會(huì)自動(dòng)運(yùn)行。你無需執(zhí)行任何操作即可導(dǎo)致上述現(xiàn)象發(fā)生。如下所示,你可以使用會(huì)話數(shù)據(jù),但是讀取,寫入和更新會(huì)話的過程是自動(dòng)的。

注解

在 CLI 下,Session 庫(kù)將自動(dòng)停止運(yùn)行,因?yàn)樗皇且粋€(gè)完全基于 HTTP 協(xié)議的概念。

關(guān)于異步的說明

除非你要開發(fā)使用 AJAX 的網(wǎng)站,否則可以跳過本節(jié)。但是,如果你遇到了性能問題,那么本說明正是你所需要的。

早期版本的 CodeIgniter 中的會(huì)話未實(shí)現(xiàn)鎖定,這意味著使用同一會(huì)話的兩個(gè) HTTP 請(qǐng)求可以完全同時(shí)運(yùn)行。使用更合適的技術(shù)術(shù)語就是,請(qǐng)求是非阻塞的。

但是,會(huì)話上下文中的非阻塞請(qǐng)求也意味著不安全,因?yàn)樵谝粋€(gè)請(qǐng)求中對(duì)會(huì)話數(shù)據(jù)的修改(或會(huì)話 ID 再生)可能會(huì)干擾第二個(gè)并發(fā)請(qǐng)求的執(zhí)行。這個(gè)細(xì)節(jié)是許多問題的根源,也是 CodeIgniter 4 擁有完全重寫的 Session 庫(kù)的主要原因。

我們?yōu)槭裁匆嬖V你這個(gè)?因?yàn)樵趪L試找出性能問題的原因之后,你可能會(huì)得出結(jié)論,鎖定是問題所在,因此研究了如何刪除鎖定……

不要那樣做!刪除鎖定是 錯(cuò)誤 的,它將給你帶來更多問題!

鎖定不是問題,而是解決方案。你的問題是,你已經(jīng)打開了會(huì)話,但已經(jīng)處理了該會(huì)話,因此不再需要它。因此,你需要的是在不再需要當(dāng)前請(qǐng)求后關(guān)閉會(huì)話。

$session->destroy();

什么是會(huì)話數(shù)據(jù)?

會(huì)話數(shù)據(jù)是與特定會(huì)話 ID(cookie)關(guān)聯(lián)的數(shù)組。

如果你以前在 PHP 中使用過會(huì)話,則應(yīng)該熟悉 PHP 的 $_SESSION 全局變量 (如果不熟悉,請(qǐng)閱讀該鏈接上的內(nèi)容)。

CodeIgniter 使用與 PHP 提供的會(huì)話處理程序機(jī)制相同的方式來訪問其會(huì)話數(shù)據(jù)。使用會(huì)話數(shù)據(jù)就像操作(讀取,設(shè)置和刪除) $_SESSION 數(shù)組一樣簡(jiǎn)單。

此外,CodeIgniter 還提供 2 種特殊類型的會(huì)話數(shù)據(jù),下面將進(jìn)一步說明:閃存數(shù)據(jù)(flashdata)和臨時(shí)數(shù)據(jù)(tempdata)。

檢索會(huì)話數(shù)據(jù)

會(huì)話數(shù)組中的任何信息都可以通過 $_SESSION 全局變量獲得:

$_SESSION['item']

或通過常規(guī)訪問器方法:

$session->get('item');

或通過魔術(shù)方法,例如 getter :

$session->item

甚至可以通過會(huì)話輔助函數(shù):

session('item');

item 就是你所要獲取的項(xiàng)目所對(duì)應(yīng)的數(shù)組的鍵。例如,要將先前存儲(chǔ)的“名稱”項(xiàng)分配給 $name 變量,你可以這樣做:

$name = $_SESSION['name'];


// 或者:
$name = $session->name


// 或者:
$name = $session->get('name');

注解

對(duì)于 get() 方法,如果你要訪問的項(xiàng)目不存在,返回 NULL。

如果要檢索所有現(xiàn)有的用戶數(shù)據(jù),則可以簡(jiǎn)單地省略 item 鍵(獲取器僅適用于單個(gè)屬性值):

$_SESSION


// 或者:
$session->get();

添加會(huì)話數(shù)據(jù)

假設(shè)某個(gè)特定用戶登錄到你的網(wǎng)站。身份驗(yàn)證后,你可以將其用戶名和電子郵件地址添加到會(huì)話中,從而使你可以全局使用該數(shù)據(jù),而不必在需要時(shí)運(yùn)行數(shù)據(jù)庫(kù)查詢。

你可以把 $_SESSION 看作像其他變量一樣,將數(shù)據(jù)簡(jiǎn)單地分配給數(shù)組?;蜃鳛?$session 的屬性。

以前的 userdata 方法已被廢棄,但是你可以將包含新會(huì)話數(shù)據(jù)的數(shù)組傳遞給該 set() 方法:

$session->set($array);

此處 $array 是一個(gè)包含新數(shù)據(jù)的關(guān)聯(lián)數(shù)組,這是一個(gè)例子:

$newdata = [
    'username'  => 'johndoe',
    'email'     => 'johndoe@some-site.com',
    'logged_in' => TRUE
];


$session->set($newdata);

如果要一次為一個(gè)會(huì)話數(shù)據(jù)只添加一個(gè)值,則 set() 還支持以下語法:

$session->set('some_name', 'some_value');

如果要驗(yàn)證會(huì)話值是否存在,只需使用 isset() 以下命令進(jìn)行檢查:

// 如果'some_name'項(xiàng)目不存在或?yàn)?NULL,則返回 FALSE,反之則返回 TRUE
isset($_SESSION['some_name'])

或者你可以調(diào)用 has()

$session->has('some_name');

向會(huì)話數(shù)據(jù)推送新值

push 方法用于將新值推送到作為數(shù)組的會(huì)話值上。例如,如果“興趣愛好”鍵包含一個(gè)興趣愛好數(shù)組,則可以將新值添加到數(shù)組中,如下所示:

$session->push('hobbies', ['sport'=>'tennis']);

刪除會(huì)話數(shù)據(jù)

與其他任何變量一樣, $_SESSION 使用 unset() 通過以下方式取消設(shè)置的值:

unset($_SESSION['some_name']);


// 或者同時(shí)取消設(shè)置多個(gè)值


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

同樣,就像 set() 可以用來向會(huì)話添加信息一樣, remove() 也可以通過傳遞會(huì)話數(shù)據(jù)的鍵來刪除信息。例如,如果要從會(huì)話數(shù)據(jù)數(shù)組中刪除“some_name”:

$session->remove('some_name');

此方法還接受要取消設(shè)置的項(xiàng)目鍵數(shù)組:

$array_items = ['username', 'email'];
$session->remove($array_items);

閃存數(shù)據(jù)(Flashdata)

CodeIgniter 支持“flashdata”,這是僅對(duì)下一個(gè)請(qǐng)求可用的會(huì)話數(shù)據(jù),然后將其自動(dòng)清除。

這可能非常有用,特別是對(duì)于一次性的信息,錯(cuò)誤或狀態(tài)消息(例如:“記錄 2 已刪除”)。

應(yīng)當(dāng)注意,flashdata 變量是常規(guī)會(huì)話變量,在 CodeIgniter 會(huì)話處理程序內(nèi)部進(jìn)行管理。

要將現(xiàn)有條目標(biāo)記為“flashdata”:

$session->markAsFlashdata('item');

如果要將多個(gè)項(xiàng)目標(biāo)記為 flashdata,只需將鍵作為數(shù)組傳遞:

$session->markAsFlashdata(['item', 'item2']);

要添加閃存數(shù)據(jù):

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

或者使用以下 setFlashdata() 方法:

$session->setFlashdata('item', 'value');

你還可以通過與 set() 相同的方式,將一個(gè)數(shù)組傳遞給 setFlashdata() 。

讀取 flashdata 變量與通過 $_SESSION 以下方式讀取常規(guī)會(huì)話數(shù)據(jù)相同:

$_SESSION['item']

重要

get() 當(dāng)通過鍵檢索單個(gè)項(xiàng)時(shí),該方法將返回 flashdata 項(xiàng)。但是,從會(huì)話中獲取所有用戶數(shù)據(jù)時(shí),它不會(huì)返回 flashdata。

但是,如果你想確定自己正在讀取“flashdata”(而不是其他種類的數(shù)據(jù)),則也可以使用以下 getFlashdata() 方法:

$session->getFlashdata('item');

或者,要獲取包含所有 flashdata 的數(shù)組,只需省略 key 參數(shù):

$session->getFlashdata();

注解

getFlashdata() 如果找不到該項(xiàng)目,則該方法返回 NULL。

如果發(fā)現(xiàn)需要通過其他請(qǐng)求保留 flashdata 變量,則可以使用 keepFlashdata() 方法來實(shí)現(xiàn)。你可以傳遞單個(gè)項(xiàng)或一組 flashdata 項(xiàng)來保留。

$session->keepFlashdata('item');
$session->keepFlashdata(['item1', 'item2', 'item3']);

臨時(shí)數(shù)據(jù)(Tempdata)

CodeIgniter 還支持“tempdata”這種具有特定到期時(shí)間的會(huì)話數(shù)據(jù)。該值過期或會(huì)話過期或被刪除后,該值將自動(dòng)刪除。

與 flashdata 相似,tempdata 變量由 CodeIgniter 會(huì)話處理程序在內(nèi)部進(jìn)行管理。

要將現(xiàn)有項(xiàng)目標(biāo)記為“tempdata”,只需將其密鑰和有效時(shí)間(以秒為單位)傳遞給該 mark_as_temp() 方法:

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

你可以通過兩種方式將多個(gè)項(xiàng)目標(biāo)記為臨時(shí)數(shù)據(jù),具體取決于你是否希望它們都具有相同的到期時(shí)間:

// “item”和“item2”都將在 300 秒后過期
$session->markAsTempdata(['item', 'item2'], 300);


// 'item'將在 300 秒后刪除,而'item2'將在 240 秒后刪除
$session->markAsTempdata([
    'item'  => 300,
    'item2' => 240
]);

添加臨時(shí)數(shù)據(jù):

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

或者使用以下 setTempdata() 方法:

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

你還可以將數(shù)組傳遞給 set_tempdata()

$tempdata = ['newuser' => TRUE, 'message' => 'Thanks for joining!'];
$session->setTempdata($tempdata, NULL, $expire);

注解

如果省略了到期時(shí)間或?qū)⑵湓O(shè)置為 0,則將使用默認(rèn)的生存時(shí)間值為 300 秒(或 5 分鐘)。

要讀取 tempdata 變量,同樣可以通過 $_SESSION 超全局?jǐn)?shù)組訪問它 :

$_SESSION['item']

重要

get() 當(dāng)通過鍵檢索單個(gè)項(xiàng)目時(shí),該方法將返回 tempdata 項(xiàng)目。但是,從會(huì)話中獲取所有用戶數(shù)據(jù)時(shí),它不會(huì)返回 tempdata。

或者,如果你想確保自己正在讀取“tempdata”(而不是其他種類的數(shù)據(jù)),則也可以使用以下 getTempdata() 方法:

$session->getTempdata('item');

當(dāng)然,如果要檢索所有現(xiàn)有的臨時(shí)數(shù)據(jù):

$session->getTempdata();

注解

getTempdata() 如果找不到該項(xiàng)目,則該方法返回 NULL。

如果你需要在一個(gè)臨時(shí)數(shù)據(jù)過期之前刪除它,你可以在 $_SESSION 數(shù)組里面做到

unset($_SESSION['item']);

但是,這不會(huì)刪除使該特定項(xiàng)成為 tempdata 的標(biāo)記(它將在下一個(gè) HTTP 請(qǐng)求中失效),因此,如果你打算在同一請(qǐng)求中重用同一鍵,則需要使用 removeTempdata()

$session->removeTempdata('item');

銷毀會(huì)話

要清除當(dāng)前會(huì)話(例如,在注銷過程中),你可以簡(jiǎn)單地使用 PHP 的 session_destroy() 函數(shù)或庫(kù)的 destroy() 方法。兩者將以完全相同的方式工作:

session_destroy();


// 或者


$session->destroy();

注解

這必須是你在同一請(qǐng)求期間執(zhí)行的與會(huì)話有關(guān)的最后一個(gè)操作。銷毀會(huì)話后,所有會(huì)話數(shù)據(jù)(包括 flashdata 和 tempdata)將被永久銷毀,并且在同一請(qǐng)求期間功能將無法使用。

你還可以 stop() 通過刪除舊的 session_id,銷毀所有數(shù)據(jù)并銷毀包含會(huì)話 ID 的 cookie,使用該方法完全終止會(huì)話:

$session->stop();

訪問會(huì)話元數(shù)據(jù)

在以前的 CodeIgniter 版本中,默認(rèn)情況下,會(huì)話數(shù)據(jù)數(shù)組包括 4 個(gè)項(xiàng)目:“session_id”,“ip_address”,“user_agent”,“l(fā)ast_activity”。

這是由于會(huì)話如何工作的細(xì)節(jié)所致,但現(xiàn)在在我們的新實(shí)現(xiàn)中不再需要。但是,你的應(yīng)用程序可能會(huì)依賴這些值,因此下面是訪問它們的替代方法:

  • session_id: session_id()
  • ip_address: $_SERVER['REMOTE_ADDR']
  • user_agent: $_SERVER['HTTP_USER_AGENT'] (unused by sessions)
  • last_activity: Depends on the storage, no straightforward way. Sorry!

會(huì)話首選項(xiàng)

通常,CodeIgniter 可以使所有工作立即可用。但是,會(huì)話是任何應(yīng)用程序中非常敏感的組件,因此必須進(jìn)行一些仔細(xì)的配置。請(qǐng)花點(diǎn)時(shí)間考慮所有選項(xiàng)及其效果。

你將在 app/Config/App.php 文件中找到以下與會(huì)話相關(guān)的首選項(xiàng):

配置項(xiàng) 默認(rèn) 選項(xiàng) 描述
sessionDriver CodeIgniterSessionHandlersFileHandler CodeIgniterSessionHandlersFileHandler CodeIgniterSessionHandlersDatabaseHandler CodeIgniterSessionHandlersMemcachedHandler CodeIgniterSessionHandlersRedisHandler CodeIgniterSessionHandlersArrayHandler 使用的會(huì)話驅(qū)動(dòng)程序
sessionCookieName ci_session [A-Za-z_-] characters only 會(huì)話 cookie 的名字
sessionExpiration 7200 (2 hours) Time in seconds (integer) 您希望會(huì)話持續(xù)的秒數(shù)。如果您希望會(huì)話不過期(直到瀏覽器關(guān)閉),請(qǐng)將值設(shè)置為零:0
sessionSavePath NULL None 指定存儲(chǔ)位置,取決于所使用的驅(qū)動(dòng)程序。
sessionMatchIP FALSE TRUE/FALSE (boolean) 讀取會(huì)話 cookie 時(shí)是否驗(yàn)證用戶的 IP 地址。 請(qǐng)注意,某些 ISP 會(huì)動(dòng)態(tài)更改 IP,因此,如果您希望會(huì)話不過期,可能會(huì)將其設(shè)置為 FALSE。
sessionTimeToUpdate 300 Time in seconds (integer) 此選項(xiàng)控制會(huì)話類重新生成自身并創(chuàng)建新的頻率。會(huì)話 ID。將其設(shè)置為 0 將禁用會(huì)話 ID 再生。
sessionRegenerateDestroy FALSE TRUE/FALSE (boolean) 自動(dòng)重新生成時(shí)是否銷毀與舊會(huì)話 ID 相關(guān)聯(lián)的會(huì)話 ID。 設(shè)置為 FALSE 時(shí),垃圾收集器稍后將刪除數(shù)據(jù)。

注解

作為最后的選擇,如果未配置上述任何項(xiàng),則會(huì)話庫(kù)將嘗試獲取 PHP 的與會(huì)話相關(guān)的 INI 設(shè)置以及舊式 CI 設(shè)置,例如“sess_expire_on_close”。但是,你永遠(yuǎn)不要依賴此行為,因?yàn)樗赡軐?dǎo)致意外的結(jié)果或?qū)肀桓?。?qǐng)正確配置所有內(nèi)容。

除了上述值之外,cookie 和本機(jī)驅(qū)動(dòng)程序還應(yīng)用了 IncomingRequestSecurity 類共享的以下配置值:

配置項(xiàng) 默認(rèn) 描述
cookieDomain ‘’ 會(huì)話適用的域
cookiePath / 會(huì)話適用的路徑
cookieSecure FALSE 是否僅在加密(HTTPS)連接上創(chuàng)建會(huì)話 cookie

注解

“cookieHTTPOnly”設(shè)置對(duì)會(huì)話沒有影響。出于安全原因,始終啟用 HttpOnly 參數(shù)。此外,“cookiePrefix”設(shè)置被完全忽略。

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

如前所述,Session 庫(kù)帶有 4 個(gè)處理程序或存儲(chǔ)引擎,你可以使用它們:

  • CodeIgniterSessionHandlersFileHandler
  • CodeIgniterSessionHandlersDatabaseHandler
  • CodeIgniterSessionHandlersMemcachedHandler
  • CodeIgniterSessionHandlersRedisHandler
  • CodeIgniterSessionHandlersArrayHandler

默認(rèn)情況下,在 FileHandler 初始化會(huì)話時(shí)將使用驅(qū)動(dòng)程序,因?yàn)樗亲畎踩倪x擇,并且有望在任何地方都可以使用(實(shí)際上每個(gè)環(huán)境都有一個(gè)文件系統(tǒng))。

但是,可以選擇通過 app/Config/App.php 文件中的 public $sessionDriver 行選擇任何其他驅(qū)動(dòng)程序。請(qǐng)記住,每個(gè)駕駛員都有不同的警告,因此在做出選擇之前,一定要使自己熟悉(如下)。

注解

在測(cè)試期間使用 ArrayHandler 并將其存儲(chǔ)在 PHP 數(shù)組中,同時(shí)防止數(shù)據(jù)被持久保存。

FileHandler 驅(qū)動(dòng)程序(默認(rèn))

“FileHandler”驅(qū)動(dòng)程序使用你的文件系統(tǒng)來存儲(chǔ)會(huì)話數(shù)據(jù)。

可以肯定地說,它的工作原理與 PHP 自己的默認(rèn)會(huì)話實(shí)現(xiàn)完全相同,但是如果這對(duì)你來說是一個(gè)重要的細(xì)節(jié),請(qǐng)記住,它實(shí)際上不是相同的代碼,并且有一些限制(和優(yōu)點(diǎn))。

更具體地說,它不支持 directory level and mode formats used in session.save_path ,并且為了安全起見,大多數(shù)選項(xiàng)都經(jīng)過硬編碼。相反, public $sessionSavePath 僅支持絕對(duì)路徑。

你還應(yīng)該知道的另一件事是,確保不要使用公共可讀或共享目錄來存儲(chǔ)會(huì)話文件。確保 只有你 有權(quán)查看所選 sessionSavePath 目錄的內(nèi)容。否則,任何能夠做到這一點(diǎn)的人都可以竊取當(dāng)前的任何會(huì)話(也稱為“會(huì)話固定”攻擊)。

在類似 UNIX 的操作系統(tǒng)上,這通常是通過使用 chmod 命令在該目錄上設(shè)置 0700 模式權(quán)限來實(shí)現(xiàn)的,該命令僅允許目錄所有者對(duì)目錄執(zhí)行讀取和寫入操作。但是要小心,因?yàn)?運(yùn)行 腳本的系統(tǒng)用戶通常不是你自己的,而是“www-data”之類的東西,因此僅設(shè)置這些權(quán)限可能會(huì)破壞你的應(yīng)用程序。

Instead, you should do something like this, depending on your environment 取而代之的是,你應(yīng)該根據(jù)自己的環(huán)境執(zhí)行類似的操作

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

Bonus Tip

某些人可能會(huì)選擇其他會(huì)話驅(qū)動(dòng)程序,因?yàn)槲募鎯?chǔ)通常較慢。這只有一半是正確的。

一個(gè)非?;镜臏y(cè)試可能會(huì)讓你相信 SQL 數(shù)據(jù)庫(kù)更快,但是在 99%的情況下,只有當(dāng)你只有幾個(gè)當(dāng)前會(huì)話時(shí),這才是正確的。隨著會(huì)話數(shù)的增加和服務(wù)器負(fù)載的增加(這很重要),文件系統(tǒng)將始終勝過幾乎所有的關(guān)系數(shù)據(jù)庫(kù)設(shè)置。

此外,如果只考慮性能,則可能需要研究使用 tmpfs ,(警告:外部資源),它可以使會(huì)話快速發(fā)展。

DatabaseHandler 驅(qū)動(dòng)程序

“DatabaseHandler”驅(qū)動(dòng)程序使用關(guān)系數(shù)據(jù)庫(kù)(例如 MySQL 或 PostgreSQL)來存儲(chǔ)會(huì)話。這是許多用戶中的一個(gè)流行選擇,因?yàn)樗归_發(fā)人員可以輕松訪問應(yīng)用程序中的會(huì)話數(shù)據(jù) - 它只是數(shù)據(jù)庫(kù)中的另一個(gè)表。

但是,必須滿足一些條件:

  • 你不能使用持久連接。
    - 你不能在啟用 cacheOn 設(shè)置的情況下使用連接。

為了使用“DatabaseHandler”會(huì)話驅(qū)動(dòng)程序,你還必須創(chuàng)建我們已經(jīng)提到的該表,然后將其設(shè)置為你的 $sessionSavePath 值。例如,如果你想使用“ci_sessions”作為表名,則可以這樣做:

public $sessionDriver   = 'CodeIgniter\Session\Handlers\DatabaseHandler';
public $sessionSavePath = 'ci_sessions';

然后,當(dāng)然要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)表…

對(duì)于 MySQL:

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

對(duì)于 PostgreSQL:

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


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

你還需要 根據(jù)你的“sessionMatchIP”設(shè)置 添加主鍵。以下示例在 MySQL 和 PostgreSQL 上均可使用:

// 當(dāng) sessionMatchIP = TRUE 時(shí)
ALTER TABLE ci_sessions ADD PRIMARY KEY (id, ip_address);


// 當(dāng) sessionMatchIP = FALSE 時(shí)
ALTER TABLE ci_sessions ADD PRIMARY KEY (id);


// 刪除先前創(chuàng)建的主鍵(在更改設(shè)置時(shí)使用)
ALTER TABLE ci_sessions DROP PRIMARY KEY;

你可以通過在 applicationConfigApp.php 文件中添加新行并使用要使用的組名來選擇要使用的數(shù)據(jù)庫(kù)組 :

public $sessionDBGroup = 'groupName';

如果你不想手工完成所有這些操作,則可以使用 session:migrationcli 中的命令為你生成一個(gè)遷移文件:

> php spark session:migration
> php spark migrate

該命令在生成代碼時(shí)將考慮 sessionSavePathsessionMatchIP 設(shè)置。

重要

由于缺少其他平臺(tái)上的建議性鎖定機(jī)制,因此僅正式支持 MySQL 和 PostgreSQL 數(shù)據(jù)庫(kù)。使用不帶鎖的會(huì)話會(huì)導(dǎo)致各種問題,尤其是在大量使用 AJAX 的情況下,我們不支持這種情況。 session_write_close() 如果遇到性能問題,請(qǐng)?jiān)谔幚硗陼?huì)話數(shù)據(jù)后使用。

RedisHandler 驅(qū)動(dòng)程序

注解

由于 Redis 沒有公開鎖定機(jī)制,因此該驅(qū)動(dòng)程序的鎖定由一個(gè)單獨(dú)的值模擬,該值最多可保留 300 秒。

Redis 是一種存儲(chǔ)引擎,由于其高性能而通常用于緩存并廣受歡迎,這可能也是你使用’RedisHandler’會(huì)話驅(qū)動(dòng)程序的原因。

缺點(diǎn)是它不像關(guān)系數(shù)據(jù)庫(kù)那樣普遍存在,并且需要在系統(tǒng)上安裝 phpredis PHP 擴(kuò)展,并且沒有與 PHP 捆綁在一起。很有可能,僅當(dāng)你已經(jīng)熟悉 Redis 并將其用于其他目的時(shí),才使用 RedisHandler 驅(qū)動(dòng)程序。

與“FileHandler”和“DatabaseHandler”驅(qū)動(dòng)程序一樣,你還必須通過該 $sessionSavePath 設(shè)置配置會(huì)話的存儲(chǔ)位置 。此處的格式有些不同,同時(shí)又很復(fù)雜。最好用 phpredis 擴(kuò)展的 README 文件來解釋,所以我們將簡(jiǎn)單地鏈接到它:

https://github.com/phpredis/phpredis

警告

CodeIgniter 的會(huì)話庫(kù)不使用實(shí)際的’redis’ session.save_handler。 注意上面鏈接中的路徑格式。

但是,對(duì)于最常見的情況,一個(gè)簡(jiǎn)單的 host:port 配對(duì)就足夠了:

public $sessionDiver    = 'CodeIgniter\Session\Handlers\RedisHandler';
public $sessionSavePath = 'tcp://localhost:6379';

MemcachedHandler 驅(qū)動(dòng)程序

注解

由于 Memcached 沒有公開鎖定機(jī)制,因此該驅(qū)動(dòng)程序的鎖定由一個(gè)單獨(dú)的值模擬,該值最多保留 300 秒。

除了可能的可用性外,“Memcached ”驅(qū)動(dòng)程序的所有屬性都與“RedisHandler”驅(qū)動(dòng)程序非常相似,因?yàn)?PHP 的 Memcached 擴(kuò)展是通過 PECL 分發(fā)的,并且某些 Linux 發(fā)行版使其可以作為易于安裝的軟件包使用。

除此之外,對(duì)于 Redis 并沒有任何故意的偏見,關(guān)于 Memcached 的說法沒有多大不同 - 它也是一種流行的產(chǎn)品,通常用于緩存并以其速度著稱。

但是,值得注意的是,Memcached 給出的唯一保證是將值 X 設(shè)置為在 Y 秒后過期將導(dǎo)致在 Y 秒過去之后將其刪除(但不一定要在該時(shí)間之前過期)。這種情況很少發(fā)生,但是應(yīng)該考慮,因?yàn)檫@可能會(huì)導(dǎo)致會(huì)話丟失。

$sessionSavePath 格式相當(dāng)這里簡(jiǎn)單,僅僅是一對(duì) host:port

public $sessionDriver   = 'CodeIgniter\Session\Handlers\MemcachedHandler';
public $sessionSavePath = 'localhost:11211';

Bonus Tip

還支持使用可選的 weight 參數(shù)作為第三個(gè)冒號(hào) ( :weight ) 值的多服務(wù)器配置,但是我們必須注意,我們尚未測(cè)試這是否可靠。

如果要嘗試使用此功能(后果自負(fù)),只需用逗號(hào)分隔多個(gè)服務(wù)器路徑:

// 相比于 192.0.2.1 權(quán)重為 1,本地主機(jī)將獲得更高的優(yōu)先級(jí)(5)。
public $sessionSavePath = 'localhost:11211:5,192.0.2.1:11211:1';
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)