wecenter學習筆記-Zend Session 框架

該文是wecenter學習筆記的一部分

Zend Session 框架

PHP runtime對Session的支持

  • 啟動新會話或者重用現(xiàn)有會話
bool session_start ([ array $options = [] ] )
  • 使用新生成的會話 ID 更新現(xiàn)有會話 ID
bool session_regenerate_id ([ bool $delete_old_session = false ] )
  • 設置用戶自定義會話存儲函數(shù)
bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )
  • 銷毀一個會話中的全部數(shù)據(jù)
bool session_destroy ( void )
  • 保存Session數(shù)據(jù)并結束Session
void session_write_close ( void )
  • 設置Cookie
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
  • 其它

PHP手冊-函數(shù)參考-Session 函數(shù)

Session命名空間

Zend使用命名空間來隔離不同的Session數(shù)據(jù),對應類Zend_Session_Namespace

數(shù)據(jù)仍然存放在全局變量 $_SESSION中,不同的空間的數(shù)據(jù)存放到如下的鍵下:

$_SESSION['namespace']

Session數(shù)據(jù)持久化

Zend Session默認支持兩種存儲方式:

  • 存儲到文件
  • 存儲到數(shù)據(jù)庫

Zend Session定義了規(guī)范化的持久化接口,包括:

  • open
  • close
  • read
  • write
  • destroy
  • gc

統(tǒng)一通過實現(xiàn)接口 Zend_Session_SaveHandler_Interface 來實現(xiàn)存儲到分布式緩存。

序列化session數(shù)據(jù)到數(shù)據(jù)表中

Zend_Session::setSaveHandler(new Zend_Session_SaveHandler_DbTable(array(
                'name'                  => get_table('sessions'),
                'primary'               => 'id',
                'modifiedColumn'        => 'modified',
                'dataColumn'            => 'data',
                'lifetimeColumn'        => 'lifetime',
                //'authIdentityColumn'  => 'uid'
            )));

wecenter定義了如下表存儲session:

CREATE TABLE `aws_sessions` (
  `id` varchar(32) NOT NULL COMMENT 'session id',
  `modified` int(10) NOT NULL COMMENT '修改時間',
  `data` text NOT NULL COMMENT 'Session數(shù)據(jù)',
  `lifetime` int(10) NOT NULL COMMENT '有效時間',
  PRIMARY KEY (`id`),
  KEY `modified` (`modified`),
  KEY `lifetime` (`lifetime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

字段名可以通過 Zend_Session_SaveHandler_DbTable的構造函數(shù)參數(shù)定制

創(chuàng)建和恢復Session

通過如下方式來啟動Session

Zend_Session::start();

self::$session = new Zend_Session_Namespace(G_COOKIE_PREFIX . '_Anwsion');

終止Session和Session的有效期

一般不需要主動調用writeClose, Session數(shù)據(jù)會在腳本執(zhí)行完自動保存。

Session的有效期可以通過修改php.ini[session]

; After this number of seconds, stored data will be seen as 'garbage' and
; cleaned up by the garbage collection process.
; http://php.net/session.gc-maxlifetime
session.gc_maxlifetime = 1440

rememberme

設置cookied的失效時間來實現(xiàn)remember-me

system/Zend/Session.php#rememberUntil

$cookieParams = session_get_cookie_params();

session_set_cookie_params(
    $seconds,
    $cookieParams['path'],
    $cookieParams['domain'],
    $cookieParams['secure']
    );

用戶登陸判斷

通過解密_user_login的cookie獲取用戶登陸信息,來驗證是否登陸

system/core/user.php#get_info

        if (! AWS_APP::session()->client_info AND $_COOKIE[G_COOKIE_PREFIX . '_user_login'])
        {
            $auth_hash_key = md5(G_COOKIE_HASH_KEY . $_SERVER['HTTP_USER_AGENT']);

            // 解碼 Cookie
            $sso_user_login = json_decode(AWS_APP::crypt()->decode($_COOKIE[G_COOKIE_PREFIX . '_user_login'], $auth_hash_key), true);

            if ($sso_user_login['user_name'] AND $sso_user_login['password'] AND $sso_user_login['uid'])
            {
                if ($user_info = AWS_APP::model('account')->check_hash_login($sso_user_login['user_name'], $sso_user_login['password']))
                {
                    AWS_APP::session()->client_info['__CLIENT_UID'] = $user_info['uid'];
                    AWS_APP::session()->client_info['__CLIENT_USER_NAME'] = $user_info['user_name'];
                    AWS_APP::session()->client_info['__CLIENT_PASSWORD'] = $sso_user_login['password'];

                    return true;
                }
            }

            HTTP::set_cookie('_user_login', '', null, '/', null, false, true);

            return false;
        }

也就是說,判斷用戶是否登陸過依賴的并不是session,而是存儲的cookie中的用戶信息。如果用戶密碼或用戶名修改了,登陸信息也會失效,符合設計要求。

登陸成功后還會將登陸的用戶信息存入Session Data(最終會系列化存儲),如果Session有效,即使_user_login的Cookied無效,用戶也可算是已登陸的。

URL改寫

通常,wecenter的地址如下:

http://host/?/article/8?id=1&wtf=other

其中IndexScript(?/)部分可以修改

system/config.inc.php

25 define('G_INDEX_SCRIPT', '?/');

中間部分稱為動作,格式如 /模塊名/控制器/動作/ID,具體規(guī)則為

  • 如果使用 /模塊名/控制器/動作/ID 格式 Query string 的使用可以參照 兼容性的支持

  • 如果動作在 main 控制器中可以省略, 例: account/main/login/ 等同于 account/login/

  • 如果動作名為 index 可以省略, 例: account/login/index/ 等同于 account/login/

query string參數(shù)也可以通過規(guī)則改寫

WeCenter 的查詢字符串為使用 __ 分隔參數(shù), 使用 – 為參數(shù)賦值, 在程序中直接使用 $_GET 取出內容
常規(guī)的:

account/login/?return_url=1&callback=2

WeCenter 的:

account/login/return_url-1__callback-2

兼容性支持

下面的幾種 URL 形式在程序中都是被支持的:

http://domian/index.php?/question/id-320__column-log__source-doc

http://domian/index.php?/question/320?column=log&source=doc

http://domian/index.php?/question/?id=320&column=log&source=doc

http://domian/index.php?/question/320?column-log__source-doc

http://domian/index.php?/question/320&column-log__source-doc

注意:index.php是唯一的入口,action只能通過query string傳入,并通過自定義的路由規(guī)則實現(xiàn)url到action的映射,具體rewrite的實現(xiàn)參照

system/core/url.php

URL最終被解析為

  • app_dir
  • controller
  • action
  • $_GET

模版視圖渲染框架Savant3 ←o→ Action路由

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容