Yaf
提供了这种机制:
可以在控制器的public属性 $actions 中定义一个或多个键值对,键为动作名字,值为定义该动作所在的文件路径。如果所请求的action在本控制器中没有相对应的方法,而在$actions中存在的话,该控制器就会载入$actions中对应的文件,实例化该动作类,执行该动作类的execute()方法。
这种机制对于多个控制器之间共享同一个动作是非常有用的。
这种定义在控制器外部的动作类(为了方便,称之为Action类)必须:
- 继承自
Yaf_Action_Abstract
类 - 实现
execute()
方法
Yaf_Action_Abstract
类继承自Yaf_Controller_Abstract
,因此,Yaf_Controller_Abstract
类的非私有方法都可以在Action类中使用。
测试
- 1.在application/controllers/Index.php中加入如下代码:
public $actions = array(
'download' => 'actions/Download.php'
);
该代码表示如果访问 /index/download,但是Index.php的IndexController中没有定义downloadAction()
方法的话,就调用actions/Download.php(路径相对于application)。
- 2.Download.php (位于 application/actions目录下)
<?php
class DownloadAction extends Yaf_Action_Abstract
{
public function execute()
{
echo __METHOD__, "<br/>";
echo "From Controller: ", $this->getController()->_name, "<br/>";
echo "Invoke method in Controller: ", $this->getController()->doSomething(), "<br/>";
}
}
用Action类的getController()
方法获取调用它的控制器实例,有了这个控制器实例,可以调用该控制器的public方法。本例中是doSomething()
。
public function doSomething()
{
echo __METHOD__, "<br/>";
}
访问 yaf.cc/index/download
首先是index控制器的初始化,然后,由于download动作在本控制器中并没有对应的方法定义,幸好其$actions属性中有download对应的值,于是,Yaf载入 actions/Download.php文件,实例化DownloadAction类,执行execute()
方法。
execute()
方法中获取调用它的控制器,然后又反过来调用控制器的doSomething()
方法。
总结
不多说了,该机制与yii框架中的action机制有异曲同工之妙,使得控制器很灵活。