[TOC]
原本一心想建立一个强大无比的框架,然后再开发各种牛逼透顶的应用的。
但是我的框架啊拖了四年都每次夭折啊。
原本还想继续拖着,直到我遇见Yii框架,靠,这TM思路不是和我一模一样嘛?连框架路径名字都一样叫做framework?难道……
所以决定就用Yii了。
表单生成和验证
-
表单提交整个过程一般是从view的页面开始的,提交到control/action对应的方法中,然后调用model实例进行save等操作。
-
表单的数据提交到control后,首先需要实例化对应的model,然后把$_POST数据赋予$model->attributes,这样会把$_POST中的属性和值赋予到$model->属性=值。
-
验证表单字段时可以使用CModel类中的rules方法配置过滤,也可以使用一个额外的LoginForm类完成登录验证,LoginForm类继承CFormModel,CFormModel其中主要提供一个基于事件的表单处理机制,因为这个过程是不需要数据库操作的而只是基于验证场景的。
因为CFormModel继承CModel,所以其本身也能重写rules方法独立完成validate过程。
-
rules方法的规则建立后,只能通过手动执行$实例->validate()或者其在执行save动作的时候会自动执行。
-
也可以在model类比如User类中定义rules进行过滤操作(因为一般继承链User->CActiveRecord->CModel),在control中执行的时候,调用model类
$model=new User('register')
其中register为scenario(场景),给User类定义场景主要是当其调用rules进行验证参数的时候,需要对不同场景进行对应的过滤。
-
rules的规则中的on对应scenario(场景),这些场景主要使用action,通过new model的时候设定,也可以是insert,update,delete等场景。其中的第二个参数的验证方法也可以是自定义。具体rules的规则看这儿。
用户身份验证
-
用户验证类为UserIdentity,是用来验证用户输入的用户名和密码是否通过的类,验证方法输入为用户名和密码,返回为错误码,如果正确的话会把用户信息name,password存入本类中。
-
UserIdentity位于应用的component目录下作为一个组件存在。
-
继承关系如下:
UserIdentity[应用中]->CUserIdentity[框架中]->CBaseUserIdentity[抽象类]->CComponent[组件]IUserIdentity[接口]
实现具体方法->包含username,password成员和构造方法,无auth实现->定义错误码等->定义接口
-
这个类一般用于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; }
用户登录
-
一般在上面的用户验证完成后,进入用户登录组件,一般使用
Yii::app()->user->login($this->_identity,$duration);
完成,这儿调用的是框架下的CWebUser类的login方法实现,主要实现用户的session机制。
其中的$this->_identity为已经完成验证步骤的loginForm类的实例。
-
当用户完成登陆后,用户信息会存在Yii::app()->user中,可以在其中获取。用的多的如下
Yii::app()->user->name Yii::app()->user->id Yii::app()->user->isGuest
-
对于不同的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。 -
对于过滤器也可以自己写,然后调用,方法如这。
密码加密
-
在Yii中提供了一个内置的crypt模块来生成密码hash,所以需要安装crypt。
md5显然是不安全的,虽然不可逆,网上已经有这么多md5反查的网站。不过md5+salt我觉得已经足够安全了,实在不明白为什么搞这么多名堂。
-
CPasswordHelper类中,使用hashPassword($password,$cost)来生成hash,其中cost是一个整数参数,用来决定加密复杂度,数字越高越复杂。其加密的密码不超过64个字节。
-
使用verifyPassword($password, $hash)来验证两个密码是否一致。这两个方法都是静态的。
创建小物件
-
在应用components目录下建立小物件,TabWidget.php,里面的类继承CWidget
class UserLeftTabWidget extends CWidget { public function run() { $this->render('tab', array()); } }
-
然后在components目录下建立views目录,里面建立tab.php文件,写好views的内容。
-
使用
<?php $this->widget('UserLeftTabWidget');?>
调用
调用扩展类
当我需要使用curl扩展的时候,按照如下方法调用
-
在项目的protected/extensions下下载扩展,或者新建curl目录,下包含Curl.php文件。
-
在配置文件的components下标下添加:
'curl' => array( 'class' => 'application.extensions.curl.Curl', 'options' => array( 'setOptions' => array( CURLOPT_HEADER => false, ), ), ),
-
使用
Yii::app()->curl->run($url);
来调用,其中返回实例化的类。