[TOC]

原本一心想建立一个强大无比的框架,然后再开发各种牛逼透顶的应用的。

但是我的框架啊拖了四年都每次夭折啊。

原本还想继续拖着,直到我遇见Yii框架,靠,这TM思路不是和我一模一样嘛?连框架路径名字都一样叫做framework?难道……

所以决定就用Yii了。

表单生成和验证

  1. 表单提交整个过程一般是从view的页面开始的,提交到control/action对应的方法中,然后调用model实例进行save等操作。

  2. 表单的数据提交到control后,首先需要实例化对应的model,然后把$_POST数据赋予$model->attributes,这样会把$_POST中的属性和值赋予到$model->属性=值。

  3. 验证表单字段时可以使用CModel类中的rules方法配置过滤,也可以使用一个额外的LoginForm类完成登录验证,LoginForm类继承CFormModel,CFormModel其中主要提供一个基于事件的表单处理机制,因为这个过程是不需要数据库操作的而只是基于验证场景的。

    因为CFormModel继承CModel,所以其本身也能重写rules方法独立完成validate过程。

  4. rules方法的规则建立后,只能通过手动执行$实例->validate()或者其在执行save动作的时候会自动执行。

  5. 也可以在model类比如User类中定义rules进行过滤操作(因为一般继承链User->CActiveRecord->CModel),在control中执行的时候,调用model类

    $model=new User('register')
    

    其中register为scenario(场景),给User类定义场景主要是当其调用rules进行验证参数的时候,需要对不同场景进行对应的过滤。

  6. rules的规则中的on对应scenario(场景),这些场景主要使用action,通过new model的时候设定,也可以是insert,update,delete等场景。其中的第二个参数的验证方法也可以是自定义。具体rules的规则看这儿

用户身份验证

  1. 用户验证类为UserIdentity,是用来验证用户输入的用户名和密码是否通过的类,验证方法输入为用户名和密码,返回为错误码,如果正确的话会把用户信息name,password存入本类中。

  2. UserIdentity位于应用的component目录下作为一个组件存在。

  3. 继承关系如下:

    UserIdentity[应用中]->CUserIdentity[框架中]->CBaseUserIdentity[抽象类]->CComponent[组件]IUserIdentity[接口]

    实现具体方法->包含username,password成员和构造方法,无auth实现->定义错误码等->定义接口

  4. 这个类一般用于login时验证,一般在建立应用是需要重写authenticate方法,注意重写的时候要重写getId和getName方法,在后续用户登录中要使用,如下

    public function authenticate()
    {
            $user = User::model()->findByAttributes(array("email" => $this->email));
            if (empty($user))-
                $this->errorCode = self::ERROR_USERNAME_INVALID;
            elseif (!CPasswordHelper::verifyPassword($this->password, $user->password))
                $this->errorCode = self::ERROR_PASSWORD_INVALID;
            else {
                $this->id = $user->id;
                $this->name = $user->username;
                $this->errorCode = self::ERROR_NONE;
            }   
            return !$this->errorCode;
    }
    

用户登录

  1. 一般在上面的用户验证完成后,进入用户登录组件,一般使用

    Yii::app()->user->login($this->_identity,$duration);
    

    完成,这儿调用的是框架下的CWebUser类的login方法实现,主要实现用户的session机制。

    其中的$this->_identity为已经完成验证步骤的loginForm类的实例。

  2. 当用户完成登陆后,用户信息会存在Yii::app()->user中,可以在其中获取。用的多的如下

    Yii::app()->user->name
    Yii::app()->user->id
    Yii::app()->user->isGuest
    
  3. 对于不同的action,有些页面是登陆用户才可访问的,有些是管理员才可见的,这种控制的Yii中统一到了controller中filter方法中。

    一般我们可以使用内置的accessController方法

       public function filters() 
        { 
            return array( 
                'accessControl', 
            ); 
        } 
    
       public function accessRules() 
        { 
            return array( 
                array('deny', 
                    'actions'=>array('create', 'edit'), 
                    'users'=>array('?'), 
                ), 
                array('allow', 
                    'actions'=>array('delete'), 
                    'roles'=>array('admin'), 
                ), 
                array('deny', 
                    'actions'=>array('delete'), 
                    'users'=>array('*'), 
                ), 
            ); 
        }
    

    在所示方法里,首先使用filter方法调用内置的accessController方法,这样则需要在controller类里重写accessRules方法。
    访问规则通过如下的上下文参数设置:
    actions: 设置哪个动作匹配此规则。
    users: 设置哪个用户匹配此规则。此当前用户的name 被用来匹配. 三种设定字符在这里可以用:
    *: 任何用户,包括匿名和验证通过的用户。
    ?: 匿名用户。
    @: 验证通过的用户。
    roles: 设定哪个角色匹配此规则。这里用到了将在后面描述的role-based access control技术。In particular, the rule is applied if CWebUser::checkAccess returns true for one of the roles.提示,用户角色应该被设置成allow规则,因为角色代表能做某些事情。
    ips: 设定哪个客户端IP匹配此规则。
    verbs: 设定哪种请求类型(例如:GET, POST)匹配此规则。
    expression: 设定一个PHP表达式。它的值用来表明这条规则是否适用。在表达式,你可以使用一个叫$user的变量,它代表的是Yii::app()->user。

  4. 对于过滤器也可以自己写,然后调用,方法如这

密码加密

  1. 在Yii中提供了一个内置的crypt模块来生成密码hash,所以需要安装crypt。

    md5显然是不安全的,虽然不可逆,网上已经有这么多md5反查的网站。不过md5+salt我觉得已经足够安全了,实在不明白为什么搞这么多名堂。

  2. CPasswordHelper类中,使用hashPassword($password,$cost)来生成hash,其中cost是一个整数参数,用来决定加密复杂度,数字越高越复杂。其加密的密码不超过64个字节。

  3. 使用verifyPassword($password, $hash)来验证两个密码是否一致。这两个方法都是静态的。

创建小物件

  1. 在应用components目录下建立小物件,TabWidget.php,里面的类继承CWidget

    class UserLeftTabWidget extends CWidget {
         public function run() {
             $this->render('tab', array());
         }
    }
    
  2. 然后在components目录下建立views目录,里面建立tab.php文件,写好views的内容。

  3. 使用

    <?php $this->widget('UserLeftTabWidget');?>
    

    调用

调用扩展类

当我需要使用curl扩展的时候,按照如下方法调用

  1. 在项目的protected/extensions下下载扩展,或者新建curl目录,下包含Curl.php文件。

  2. 在配置文件的components下标下添加:

    'curl' => array(
                'class' => 'application.extensions.curl.Curl',
                'options' => array(
                    'setOptions' => array(
                         CURLOPT_HEADER => false,
                        ),  
                    ),  
            ),
    
  3. 使用

    Yii::app()->curl->run($url);
    

    来调用,其中返回实例化的类。