wecenter学习笔记-Zend Session 框架

该文是wecenter学习笔记的一部分

Zend Session 框架

PHP runtime对Session的支持

  • 启动新会话或者重用现有会话
bool session_start ([ array $options = [] ] )
  • 使用新生成的会话 ID 更新现有会话 ID
bool session_regenerate_id ([ bool $delete_old_session = false ] )
  • 设置用户自定义会话存储函数
bool session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc [, callable $create_sid ] )
  • 销毁一个会话中的全部数据
bool session_destroy ( void )
  • 保存Session数据并结束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手册-函数参考-Session 函数

Session命名空间

Zend使用命名空间来隔离不同的Session数据,对应类Zend_Session_Namespace

数据仍然存放在全局变量 $_SESSION中,不同的空间的数据存放到如下的键下:

$_SESSION['namespace']

Session数据持久化

Zend Session默认支持两种存储方式:

  • 存储到文件
  • 存储到数据库

Zend Session定义了规范化的持久化接口,包括:

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

统一通过实现接口 Zend_Session_SaveHandler_Interface 来实现存储到分布式缓存。

序列化session数据到数据表中

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数据',
  `lifetime` int(10) NOT NULL COMMENT '有效时间',
  PRIMARY KEY (`id`),
  KEY `modified` (`modified`),
  KEY `lifetime` (`lifetime`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

字段名可以通过 Zend_Session_SaveHandler_DbTable的构造函数参数定制

创建和恢复Session

通过如下方式来启动Session

Zend_Session::start();

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

终止Session和Session的有效期

一般不需要主动调用writeClose, Session数据会在脚本执行完自动保存。

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的失效时间来实现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,具体规则为

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

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

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

query string参数也可以通过规则改写

WeCenter 的查询字符串为使用 __ 分隔参数, 使用 – 为参数赋值, 在程序中直接使用 $_GET 取出内容
常规的:

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传入,并通过自定义的路由规则实现url到action的映射,具体rewrite的实现参照

system/core/url.php

URL最终被解析为

  • app_dir
  • controller
  • action
  • $_GET

模版视图渲染框架Savant3 ←o→ Action路由

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容