天天看點

雲客Drupal源碼分析之Session系統

Session在網站中扮演非常重要的角色,儲存臨時使用者資料、登入資料等等都用到了它,Drupal使用到了Symfony的Session元件,該元件非常強大靈活,drupal在此基礎上有所改造和擴充,要了解Symfony的Session元件讓我們先從原生php的Session機制說起:

php原生的Session采用伺服器檔案系統儲存使用者會話資料,這對一般小型網站足夠了,但php做的遠非如此,它提供了一整套機制讓使用者可以自定義Session的實作,比如加密儲存、資料放資料庫等等,我們看一看Session是如何實作的:

實作Session有7個方法open, close, read, write, destroy, gc , create_sid,不管是原生、php擴充、還是使用者自定義機制都是使用它們,使用session_set_save_handler()函數注冊後,Session機制就會調用這些方法使用它們内部定義的邏輯去儲存會話資料,關于詳細資訊請看官方文檔,在php5.4開始php定義了Session處理器接口SessionHandlerInterface以及此接口的預設實作 SessionHandler ,使用者可以自己去實作該接口,接口定義了以上7個方法,這些方法會被php内部自動調用,無需使用者幹預,php會把調用結果填充到$_SESSION超全局變量裡,這個接口的實作這裡把它稱為存儲處理器,有了它我們就可以在裡面實作資料庫存儲邏輯等等了。

下面來看一看Symfony的Session元件是怎麼運作的,先看一張圖:

雲客Drupal源碼分析之Session系統

整個Session系統向使用者提供一個統一的界面,由 SessionInterface接口定義,在内部分為兩大部分:

SessionBagInterface:資料包接口,用于管理最終使用者的資料,這裡稱之為資料包管理器

SessionStorageInterface:儲存處理接口,用于處理資料的儲存、Session ID配置設定等,這裡稱為儲存管理器

資料管理器預設提供了三大類:

AttributeBag:屬性包,通常使用的資料就存放在這裡

FlashBag:閃存包,應對一些特殊用途,資料隻能被取出一次,用後即毀

MetadataBag:中繼資料包,用于存儲Session資料本身的一些中繼資料,比如Session建立的時間、最後使用時間、生命周期

在SessionBagInterface接口裡面我們可以看到兩個屬性:Name和StorageKey,Name好了解,它用于辨別這個資料包,但StorageKey是什麼意思?其實資料包裡面的資料都是儲存在$_SESSION裡面,資料包管理器本身隻是儲存一個引用而已,真正的資料在$_SESSION[$StorageKey]裡。每個包都對應着$_SESSION的一個子數組,這樣就實作了Session也可以和其他第三方軟體相容,包是如何和$_SESSION[$StorageKey]關聯的呢?這就是接口裡面initialize(array &$array)方法的工作。

下面看一看儲存管理器:

Symfony預設實作了一個儲存管理器:NativeSessionStorage,它封裝了php的原生Session使用,使用php原生的儲存處理器SessionHandlerInterface

我們在示例化Session的時候可以傳入自定義的儲存管理器及包管理器,構造函數如下:

__construct(SessionStorageInterface $storage = null, AttributeBagInterface $attributes = null, FlashBagInterface $flashes = null)

在不提供任何參數時直接使用php原生機制,不同的是它已經被包裝成了面向對象方式

use Symfony\Component\HttpFoundation\Session\Storage\Session\Session;

$Session=new Session();
$Session->set($name, $value);
           

以上就是Symfony的Session元件原理。

drupal8有所改進,包括儲存Session到資料庫,詳見\core\lib\Drupal\Core\Session

它涉及到使用者賬戶接口,另外再讨論

我是雲客,【雲遊天下,做客四方】,聯系方式見首頁,歡迎轉載,但須注明出處