美文网首页
wecenter学习笔记-Zend Session 框架

wecenter学习笔记-Zend Session 框架

作者: imhaiyang | 来源:发表于2016-07-11 18:41 被阅读640次

    该文是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路由

    相关文章

      网友评论

          本文标题:wecenter学习笔记-Zend Session 框架

          本文链接:https://www.haomeiwen.com/subject/ocsjjttx.html