入口文件index.php流程
//用于调试的配置常量: define('YII_DEBUG',true); //启用调试,默认为false define('YII_TRACE_LEVEL',3); //出错时错误信息显示的调用堆栈深度,默认为0 //以上选项必须在require yii.php之前定义 //加载Yii框架启动文件 require_once(‘Yii/framework/yii.php’);
$config=”protected/config/main.php”;//既可以为配置文件路径,也可以为包含配置选项的数组 //即,也可以 $config=(require ”protected/config/main.php”;);
$app=Yii::createWebApplication($config);//创建WebApplication实例 //$app=new CWebApplication($config);
$app->run(); //运行Controller
|
- 设置Yii::app()为当前运行实例
- BasePath及PathAlias设置
- preinit()(未实现)
- 注册ErrorHandler和ExceptionHandler
- 注册系统核心组件
- 应用配置(main.php中的配置将对核心组件起作用)
- 加载Behaviors(main.php中的配置对此处加载的扩展—— behaviors配置项,不起作用)
- 加载Components(main.php中的配置对此处加载的组件不起作用)
- init() ——初始化request组件
CApplication实例->init() ->getRequest() -> Yii::createComponent(‘request’);
request组件为系统核心组件
- $c=Yii::createComponent(array(‘class’=>’CHttpRequest’)) //new CHttpRequest
- $c->init() //Normalize Request,如果开启CSRF校验,则注册beginRequest事件的回调函数$c->validateCsrfToken
- 触发onBeginRequest事件,(如果开启CSRF校验,则运行Handler validateCsrfToken)
- processRequest,运行Controller,流程请参见Controller
- 触发onEndRequest事件,正常结束请求返回
import($alias,$forceInclude=false): $alias为path.to.class形式,将被转换为类文件的路径 path/to/class.php 可以预先使用setPathOfAlias设置path别名,如:Yii::setPathOfAlias('ext',$this->getBasePath().'/extensions'); import方法只是将此路径添加到include_path中,当真正用到此类时才include这个文件将$forceInclude设为true可以立即include类文件 $alias解释:
以下为CApplication::__construct中设置的alias
|
createComponent($config): createComponent接受的参数形式
方法返回被创建的组件对象 |
trace($msg):
输入LEVEL_TRACE的Log |
log($msg,$level=CLogger::LEVEL_INFO,$category='application'):
记录日志,可通过CLogger::getLogs()获得已经记录的日志 |
app(): 返回当前运行的CApplication实例 |
CApplication支持四个自定义事件
|
Contructor参数$config
|
CModule实现功能:
|
public $preload=array(‘name1’,’name2’); 预加载的组件 |
getComponent($id,$createIfNull=true) 根据组件名称获取组件对象,也可以直接通过 $m->componentName获取组件对象
getComponent($config); $config=array(‘class’=>’className’,’property1’=>’value1’...);
Yii::app()->log ;//获取log组件 |
CComponent CComponent实现了以下三个功能:
| |
| |
| |
| |
属性读取将先尝试Compoent公共属性,setter与getter,再尝试Component的事件属性 最后尝试$behavior的属性方法及事件 |
CComponent::raiseEvent($name,$event);第二个参数必须为CEvent类型
$event=new CEvent($sender); //$sender可以为任何对象,之后可通过$event->sender读取 $event->handled=true;/*设置一个bool值,默认false,设为true之后可阻止此事件相关的 其它handler被调用(类似于JS Event的stopPropagation)*/ |
枚举类型,没有任何方法及属性,仅用作被所有只包含const的枚举类所继承 |
按Yii规约,Web程序配置文件为protected/config/main.php中,测试用配置文件为protected/config/test.php
配置文件必须返回一个关联数组,关联数组$config将作为构造参数传递给CApplication构造函数,$config[‘basePath’]将被设置为命名空间别名”application”的值(即应用程序protected目录) 所有其它的键-值将被批量赋值为CWebApplication的属性-值 | ||||||||||||||||||||||
| ||||||||||||||||||||||
| ||||||||||||||||||||||
|
//启用URLManager Component (main.php array(‘components’)) 'urlManager'=>array( 'urlFormat'=>'path', 'rules'=>array( '<controller:\w+>/<id:\d+>'=>'<controller>/view', '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>', '<controller:\w+>/<action:\w+>'=>'<controller>/<action>', ), 'showScriptName'=>false //去掉index.php )
//在根目录下添加.htaccess文件,内容为 RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L] RewriteRule ^.*$ index.php [NC,L]
|
- $app->processRequest,解析获取route(“controllerID/actionID”形式字符串)
- 开启catchAllRequest,则使用此此配置(@see catchAllRequest)
- UrlManager根据rules,urlFormat等(urlManager配置)解析返回route
- $app->runController($route),创建Controller实例,初始化:init(),调用:run($actionID)
- 构造,注册behaviors(@see Controller::behaviors())
- init()方法由用户实现
- run($actionID)
- 创建CAction实例
- 运行Controller所属的Module(CWebApplication实例)的beforeControllerAction($controller,$action)方法
- 应用filters(@see filters())运行Action
- 运行Controller所属的Module(CWebApplication实例)的afterControllerAction($controller,$action)方法
- UrlManager找不到对应的Controller,则抛出CHttpException 404 异常
- CApplication::handleException处理异常
- 触发onException事件,如果Event没有被挂起(handled设为true),继续
- 查看是否加载了ErrorHandler组件,交由CErrorHandler处理
- 如果异常没被处理,则直接显示错误信息
‘components’=>array(
‘errorHandler’=>array(
‘errorAction’=>’site/error’ //用来处理404的Action
)
)
执行Controller::missingAction方法,此方法默认抛出一个CHttpException 404 异常
可在子类中override missingAction方法
init(): 用于初始化,在实例创建完成,run具体action之前执行 |
在构造时给Controller添加扩展,返回包含behavior配置的关联数组 值的形式同配置项::behaviors |
filters():array 返回在action执行之前执行的filters列表,REF |
missingAction($actionID): 创建Action失败时,则执行missingAction方法 |
actions(): 当action对应方法找不到时,在此方法返回的ActionMap中查找,REF 自定义Action必须继承自CAction ,REF |
accessRules(): 返回访问规则数组,REF |
InlineFilter:Controller::filterFilterName形式
InlineFilter配置
return array(
‘filterName [+|- action1,action2...]’,
)
实现InlineFilter的方法签名
public function filterFilterName($chain) {}
验证通过时执行$chain->run()方法以继续执行下一个filter
CController实现了
- filterPostOnly方法
- filterAjaxOnly方法
- filterAccessControl方法
ClassFilter:继承自CFilter的类(@see CFilter)
推荐在实现自定义ClassFilter时,采用重写preFilter的方法,而不去重写filter方法
CFilter |
filter($filterChain): 执行 filter操作,正常通过时执行$filterChain->run()以继续 |
init(): 构造完成后运行以初始化 |
preFilter($filterChain): 在继承CFilter子类时不去override filter方法,而只覆盖preFilter方法,此方法返回true或false决定filter是否正常通过 |
postFilter($filterChain): 结合preFilter,只在子类没有覆盖filter方法,只实现preFilter方法时,preFilter正常通过后且执行了$filterChain->run()之后执行 |
- allowAutoLogin=false;//是否允许基于cookie的自动登录,如果设为false,所有用户数据将保存到SESSION中
- guestName=’Guest’;//没有登录的用户的name
- loginUrl=array(‘site/login’);//跳转到的登录页面URL
- identityCookie;//用于配置用于身份验证Cookie的其它属性,参见CHttpCookie属性,此选项仅在allowAutoLogin设为true可用
- autoRenewCookie=false;//设置是否每次访问都重新生成用于身份验证的Cookie,此选项仅在allowAutoLogin设为true可用
- returnUrl;//用户登录后跳转到的URL
- login(IUserIdentity $identity, integer $duration=0);参见UserIdentity
- logout(boolean $destroySession=true);
- checkAccess(string $operation, array $params=array ( ), boolean $allowCaching=true);//参见Auth
实现
- 继承自CUserIdentity
- 实现authenticate方法,通过$this->username和$this->password进行认证,方法返回true表示认证成功
User State
- 在UserIdentity中重写getPersistenceStates方法,返回需要保存到Cookie中的用户数据(这部分数据不能包含用来认证的数据-比如password)的关联数组
- 对于登录用户,可以通过Yii::app()->user->stateName获取保存的state值
使用
//登录 $identity=new UserIdentity($username,$password); if ($identity->authenticate()) { //Yii::app()->user对象为CWebUser实例 Yii::app()->user->login($identity,$expires); }
//权限验证 Yii::app()->user->checkAccess($operation); |
相关参考
CHttpCookie属性:
- name
- value=’’
- domain=’’
- expire=0
- path=’/’
- secure=false
- httpOnly=false
- 对需要AccessControl的action设置filters规则
- 覆写Controller::accessRules方法,返回权限验证规则
//返回访问权限规则 public function accessRules() { return array( 'allow', // or 'deny' // optional, list of action IDs (case insensitive) that this rule applies to 'actions'=>array('edit', 'delete'), // optional, list of controller IDs (case insensitive) that this rule applies to // This option is available since version 1.0.3. 'controllers'=>array('post', 'admin/user'), // optional, list of usernames (case insensitive) that this rule applies to // Use * to represent all users, ? guest users, and @ authenticated users 'users'=>array('thomas', 'kevin'), // optional, list of roles (case sensitive!) that this rule applies to. 'roles'=>array('admin', 'editor'), // optional, list of IP address/patterns that this rule applies to // e.g. 127.0.0.1, 127.0.0.* 'ips'=>array('127.0.0.1'), // optional, list of request types (case insensitive) that this rule applies to 'verbs'=>array('GET', 'POST'), // optional, a PHP expression whose value indicates whether this rule applies // This option is available since version 1.0.3. 'expression'=>'!$user->isGuest && $user->level==2', // optional, the customized error message to be displayed // This option is available since version 1.1.1. 'message'=>'Access Denied.', ); }
//应用AccessControlFilter public function filters() { return array( 'accessControl',//对所有action应用访问权限控制 'accessControl + profile',//仅对profile一个action使用 'accessControl - login,register',//对除login,register以外的action使用 ); }
|
配置项
return array(
‘components’=>array(
‘log’=>array(
‘class’=>’CLogRouter’,
‘routes’=>array(
‘class’=>’CFileLogRoute’, //使用CWebLogRoute将Log显示是WebPage上
‘levels’=>'error, warning',//为空则记录所有日志
)
)
)
);