Yaf_Controller_Abstract是Yaf的MVC体系的核心部分. MVC是指Model-View-Controller, 是一个用于分离应用逻辑和表现逻辑的设计模式.
Yaf_Controller_Abstract体系具有可扩展性, 可以通过继承已有的类, 来实现这个抽象类, 从而添加应用自己的应用逻辑.
对于Controller来说, 真正的执行体是在Controller中定义的一个一个的动作, 当然这些动作也可以定义在Controller外:参看Yaf_Controller_Abstract::$action
与一般的框架不同, 在Yaf中, 可以定义动作的参数, 这些参数的值来自对Request的路由结果中的同名参数值. 比如对于如下的控制器:
例 11.44. Yaf_Controller_Abstract参数动作 的例子
<?php
class IndexController extends Yaf_Controller_Abstract {
public function indexAction($name, $value) {
}
}
?>
在使用默认路由的情况下, 对于请求http://domain.com/index/index/name/a/value/2我们知道会在Request对象中生成俩个参数name和value,
而注意到动作indexAction的参数, 与此同名, 于是在indexAction中, 可以有如下两种方式来获取这俩个参数:
例 11.45. Yaf_Controller_Abstract参数动作 的例子
<?php
class IndexController extends Yaf_Controller_Abstract {
public function indexAction($name, $value) {
//直接获取参数;
echo $name, $value; //a2
//通过Request对象获取
echo $this->getRequest()->getParam("name"); //a
}
}
?>
![]() |
注意 |
|---|---|
| 需要注意的是, 这些参数是来自用户请求URL, 所以使用前一定要做安全化过滤. 另外, 为了防止PHP抛出参数缺失的警告, 请尽量定义有默认值的参数. |
在PHP5.3之后, 打开yaf.use_namespace的情况下, 也可以使用 Yaf\Controller_Abstract.
abstract Yaf_Controller_Abstract {protected arrayactions;protected Yaf_Request_Abstract_request;protected Yaf_Response_Abstract_response;protected Yaf_View_Interface_view;protected string_script_path;private void __construct ( void );public void init ( void );public string getModuleName ( void );public Yaf_Request_Abstract getRequest ( void );public Yaf_Response_Abstract getResponse ( void );public Yaf_View_Interface getView ( void );public Yaf_View_Interface initView ( void );public boolean setViewPath ( string $view_directory );public string getViewPath ( void );public Yaf_Response_Abstract render ( string $action_name ,
array $tpl_vars = NULL );public boolean display ( string $action_name ,
array $tpl_vars = NULL );public boolean forward ( string $action ,
array $invoke_args = NULL );public boolean forward ( string $controller ,
string $action ,
array $invoke_args = NULL );public boolean forward ( string $module ,
string $controller ,
string $action ,
array $invoke_args = NULL );public boolean redirect ( string $url );
}
actions有些时候为了拆分比较大的Controller, 使得代码更加清晰和易于管理, Yaf支持将具体的动作分开定义. 每个动作都需要实现 Yaf_Action_Abstract 就可以通过定义Yaf_Controller_Abstract::$actions来指明那些动作对应于具体的那些分离的类. 比如:
<?php
class IndexController extends Yaf_Controller_Abstract {
public $actions = array (
"index" => "actions/Index.php",
);
}
这样, 当路由到动作Index的时候, 就会加载APPLICATION_PATH . "/actions/Index.php", 并且在这个脚本文件中寻找IndexAction(可通过yaf.name_suffix和yaf.name_separator来改变具体命名形式), 继而调用这个类的execute方法.
![]() |
注意 |
|---|---|
| 在yaf.st_compatible打开的情况下, 会产生额外的查找逻辑. |
_request当前的请求实例, 属性的值由Yaf_Dispatcher保证, 一般通过Yaf_Controller_Abstract::getRequest来获取此属性.
_response当前的响应对象, 属性的值由Yaf_Dispatcher保证, 一般通过Yaf_Controller_Abstract::getResponse来获取此属性.
_view视图引擎, Yaf才会延时实例化视图引擎来提高性能, 所以这个属性直到显示的调用了Yaf_Controller_Abstract::getView或者Yaf_Controller_Abstract::initView以后才可用
_script_path视图文件的目录, 默认值由Yaf_Dispatcher保证, 可以通过Yaf_Controller_Abstract::setViewPath来改变这个值.
Yaf_Controller_Abstract::__construct由Yaf在分发过程中不带参数调用, 用户不应该直接调用它, 也不建议在子类中覆盖它. 如果需要在控制器实例化时运行自己的初始化逻辑, 应当使用init钩子: 如果在控制器中定义了init方法, 它会在控制器对象实例化之后立即被调用.
例 11.90. Yaf_Controller_Abstract::init 的例子
<?php
class IndexController extends Yaf_Controller_Abstract {
// init在控制器实例化之后, 任何动作被分发之前调用
public function init() {
// 此时请求, 响应和视图引擎都已装配就绪
var_dump($this->getRequest() instanceof Yaf_Request_Abstract);
var_dump($this->getResponse() instanceof Yaf_Response_Abstract);
var_dump($this->getView() instanceof Yaf_View_Interface);
}
public function indexAction() {
// ...
}
}
?>
getName返回当前控制器的名称(不带"Controller"后缀), 未设置时返回NULL:
例 11.91. Yaf_Controller_Abstract::getName 的例子
<?php
class ProductController extends Yaf_Controller_Abstract {
public function indexAction() {
var_dump($this->getName()); // string(7) "Product"
}
}
?>
通过Yaf_Controller_Abstract::forward传递给动作的调用参数, 除了可以经Yaf_Request_Abstract::getParam读取外, 也可以在目标动作中通过getInvokeArgs和getInvokeArg获取:
getInvokeArgs以参数名为键的数组形式返回当前动作的全部调用参数, 如果没有传递参数则返回NULL.
getInvokeArg根据名称返回当前动作的单个调用参数, 不存在时返回NULL.
例 11.92. getInvokeArgs/getInvokeArg 的例子
<?php
class UserController extends Yaf_Controller_Abstract {
public function indexAction() {
// 转发到本控制器的profile动作, 并携带调用参数
$this->forward("profile", array("name" => "laruence"));
return false; // 结束当前流程
}
public function profileAction() {
var_dump($this->getInvokeArg("name")); // string(8) "laruence"
var_dump($this->getInvokeArg("missing")); // NULL
var_dump($this->getInvokeArgs()); // 全部调用参数组成的数组
}
}
?>