YII框架分析笔记5:控制器和动作

CBaseController是控制器和挂件的基类,主要提供了视图渲染,挂件,剪辑、片段缓存等方法,CController是所有应用中自定义控制器的基类。

创建动作

[php] view plaincopy

  1. public function run($actionID)
  2. {
  3. if(($action=$this->createAction($actionID))!==null)
  4. {
  5. if(($parent=$this->getModule())===null)
  6. $parent=Yii::app();
  7. if($parent->beforeControllerAction($this,$action))
  8. {
  9. $this->runActionWithFilters($action,$this->filters());
  10. $parent->afterControllerAction($this,$action);
  11. }
  12. }
  13. else
  14. $this->missingAction($actionID);
  15. }

控制器的调用从CWebApplication执行runController()起,通过路由找到控制器和动作id,初始化控制器实例,然后执 行$controller->run($actionID),通过actionId创建动作对象(预留 beforeControllerAction和afterControllerAction钩子)。
如果动作方法存在于控制器中并且不是actions(),会创建一个CInlineAction对象,否则通过actions()中会返回外部动作的关联
数组射找到外部动作对象,这个好处是可以共用一些同样的动作,比如下面curd动作代码,通过http://www.test.com
/index.php?r=post/read就可以通过外部ReadAction对象读取post

[php] view plaincopy

  1. class PostController extends Controller
  2. {
  3. function actions(){
  4. return array(
  5. ‘create‘ => array(
  6. ‘class‘      => ‘application.actions.CreateAction‘,
  7. ‘modelClass‘ => ‘Post‘,
  8. ),
  9. ‘update‘ => array(
  10. ‘class‘      => ‘application.actions.UpdateAction‘,
  11. ‘modelClass‘ => ‘Post‘,
  12. ),
  13. ‘read‘ => array(
  14. ‘class‘      => ‘application.actions.ReadAction‘,
  15. ‘param‘      => ‘Postid‘,
  16. ‘modelClass‘ => ‘Post‘,
  17. ),
  18. ‘delete‘ => array(
  19. ‘class‘      => ‘application.actions.DeleteAction‘,
  20. ‘modelClass‘ => ‘Post‘,
  21. )
  22. );
  23. }
  24. }

在actions()中还可以指定CViewAction对象,它其实就是YII框架写的一个调用外部动作的一个扩展。如下面代码可以按照用户指定的参数显示一个视图,通过GET参数来定位视图文件,这样对加载静态内容而又不用单独写动作方法很有帮助。

[php] view plaincopy

  1. public function actions()
  2. {
  3. return array(
  4. ‘page‘=>array(
  5. ‘class‘=>‘CViewAction‘,
  6. ‘basePath‘ => ‘$path‘,
  7. ‘defaultView ‘=> ‘$view‘
  8. ),
  9. );
  10. }

过滤器
在创建完Action对象后,现在又返回到CController接着执行过滤动作(预留beforeControllerAction和
afterControllerAction钩子),此时会加载过滤器,控制器通过CController::filters()方法返回过滤器配置关联
数组,和验证器相似,过滤器可以在控制器内部定义(方法名必须以filter开头)也可以自定义过滤器类继承CFilter扩展preFilter()和
postFilter()方法, 如框架中自带的授权验证CAccessControlFilter。

执行动作
再返回CController执行动作(预留beforeAction和afterAction钩子),进入CActon子类(以
CInlineAction为例)中执行runWithParams($params)方法通过php反射判断控制器中的动作方法是不是需要参数
1、如果需要参数执行runWithParamsInternal()方法,通过反射获取动作方法中的参数和值得键值对数组(写API经常用的方法),并执行动作方法
2、如果不要参数执行run()方法定位到控制器的动作中

[php] view plaincopy

  1. /**
  2. * Runs the action with the supplied request parameters.
  3. * This method is internally called by {@link CController::runAction()}.
  4. * @param array $params the request parameters (name=>value)
  5. * @return boolean whether the request parameters are valid
  6. * @since 1.1.7
  7. */
  8. public function runWithParams($params)
  9. {
  10. $methodName=‘action‘.$this->getId();
  11. $controller=$this->getController();
  12. $method=new ReflectionMethod($controller, $methodName);
  13. if($method->getNumberOfParameters()>0)
  14. return $this->runWithParamsInternal($controller, $method, $params);
  15. else
  16. return $controller->$methodName();
  17. }
  18. /**
  19. * Executes a method of an object with the supplied named parameters.
  20. * This method is internally used.
  21. * @param mixed $object the object whose method is to be executed
  22. * @param ReflectionMethod $method the method reflection
  23. * @param array $params the named parameters
  24. * @return boolean whether the named parameters are valid
  25. * @since 1.1.7
  26. */
  27. protected function runWithParamsInternal($object, $method, $params)
  28. {
  29. $ps=array();
  30. foreach($method->getParameters() as $i=>$param)
  31. {
  32. $name=$param->getName();
  33. if(isset($params[$name]))
  34. {
  35. if($param->isArray())
  36. $ps[]=is_array($params[$name]) ? $params[$name] : array($params[$name]);
  37. else if(!is_array($params[$name]))
  38. $ps[]=$params[$name];
  39. else
  40. return false;
  41. }
  42. else if($param->isDefaultValueAvailable())
  43. $ps[]=$param->getDefaultValue();
  44. else
  45. return false;
  46. }
  47. $method->invokeArgs($object,$ps);
  48. return true;
  49. }
时间: 2024-10-13 22:34:07

YII框架分析笔记5:控制器和动作的相关文章

YII框架分析笔记2:组件和事件行为管理

Yii是一个基于组件.用于开发大型 Web 应用的高性能 PHP 框架.CComponent几乎是所有类的基类,它控制着组件与事件的管理,其方法与属性如下,私有变量$_e数据存放事件(evnet,有些地方叫 hook),$_m数组存放行为(behavior). 组件管理 YII是一个纯oop框架,很多类中的成员变量的受保护或者私有的,CComponent中利用php中的魔术方法__get(),__set()来访问和设置属性,但这些方法的作用远不指这些.下面用__get()来说明 [php] vi

YII框架分析笔记1:YII执行流程

yii整体执行流程直观,具体由以下步骤: 1.程序入口文件index.php加载yii框架引导程序(bootstrap)文件yii.php,加载配置文件以及其他自定义配置. 2.yii.php中Yii类继承了YiiBase,主要封装框架的一些通用方法,比如自动加载.创建组件.核心类路径映射.记录日志以及调试等,YiiBase.php中注册自动加载方法.另外Yii类预留可以自定义一些方法作为扩展. 3.回到index.php,Yii::createWebApplication($config),创

YII框架分析笔记6:视图

YII框架使用的view是在原生的php模板上进行扩展的.CController中对视图的渲染有多种方法: render($view,$data=null,$return=false)//连同layout一起渲染 renderPartial($view,$data=null,$return=false,$processOutput=false)//不渲染layout renderText($text,$return=false)//渲染静态内容和layout renderDynamic($cal

YII框架分析笔记10:日志

yii框架中日志组件记录的等级5类,在CLogger已通过常量定义: const LEVEL_TRACE='trace'; const LEVEL_WARNING='warning'; const LEVEL_ERROR='error'; const LEVEL_INFO='info'; const LEVEL_PROFILE='profile'; CLogger为所有日志写入和获取提供接口,通过日志路由管理类CLogRouter将日志分发到不同日志展现或存储介质中. 日志组件配置 [php]

YII框架分析笔记8:CDataProvider

CDataProvider,顾名思义,数据提供者,它提供了三个抽象方法(fetchData,.fetchKeys 和 calculateTotalItemCount),分别为调用不同数据结构的数据提供了获取数据.获取键值.获取数量的,接口,在YII框架 中,CActiveDataProvider.CArrayDataProvider.CSqlDataProvider是它的子类,除了提供数据之外, 他还提供分页和排序功能.下面以获取数据fetchData()为例 CActiveDataProvid

YII框架分析笔记3:表单模型和验证

表单模型CFormModel绝大部分继承CModelCModel,由于表模型数据不需要持久化,所以主要在验证操作上.下面以框架脚手架生成的网站登录为例说明表单模型. [php] view plaincopy //模型中的验证规则 public function rules() { return array( array('username, password', 'required'), array('rememberMe', 'boolean'), array('password', 'aut

YII框架分析笔记9:url路由

以创建url路由为例,从CWebApplication执行请求过程说起,如果在配置中设置了catchAllRequest,所有请求将会定位到配置中的路由中,否则的需要CUrlManager的parseUrl()方法解析解析url获取路由. [php] view plaincopy /** * Parses the user request. * @param CHttpRequest $request the request application component * @return str

YII框架分析笔记12:主题管理

YII主题的控制由CThemeManager和CTheme管理,CThemeManager在应用初始化时作为核心组件注册,主题默认路径是app/themes/. 主题配置 由于主题组件在应用初始化时注册,其配置以及很方面,比如在app/themes/下有一个custom1主题 在主配置文件中加入'theme'=>'custom1'键值对,在主题注册的时候会调用 CWebApplication::setTheme($value)初始化主题的名字. 获取主题 主题的获取从控制器渲染视图说起,通过视a

YII框架分析笔记4:ar模型和db

YII中实现两种类型的模型,分别是表单模型和活动记录.在持久化数据方面,YII只实现了活动记录,对于复杂的数据关系可以用框架提供的DAO来自己写model,对应集成doctrine这样的ORM还没有仔细研究过. ar模型 框架中的model是CModel子类,CModel主要是一些验证与错误处理,并实现迭代器和数组访问接口,活动记录模型CActiveRecord是AR模型的基类. 每个AR类代表一个单独的数据表,一个AR实例则代表那个表中的一行.AR是一种对象关系映射(ORM)的设计模式,它负责