> CakePHP中文手册 > Controller 控制器

Controller

一个controller用于管理应用程序里某一方面的逻辑。大多数来说,controller被用于管理独立model的逻辑。比如,当你想构建一个管理录像带的站点,你也许会有一个VideoController和一个RentalController分别管理你的录像带和租用记录。在Cake里边,controller的名字总是复数的形式。(译注:例如刚才提到过的VideoController,我们应该使用VideosController,而不是VideoController) 应用程序里的所有controller都是继承自Cake的 AppController的类,而AppController类又继承自核心的Controller类。每个controller可以包含任意数量的action-一些在web应用程序中用于显示视图的方法。 AppController类可以在/app/appcontroller.PHP里定义并且它应该包含那些两个或者多个controller所共享的方法。它本身继承了Cake标准类库里的Controller类。 一个action,是controller里的一个独立的方法。在进行了适当的route配置后,当页面请求指定某个action时,这个action对应的方法将被Dispatcher自动分发执行。(It is run automatically by the Dispatcher if an incoming page request specifies it in route configuration)回到我们的录像带的例子,我们的VideoController也许会包含view(), rent()和search()的action。这个controller可以在/app/controllers/videos_controller.php里找到并且包含以下内容:

你可以通过以下的示例URL来访问这些action:

Http://www.example.com/videos/view/253
http://www.example.com/videos/rent/5124/0-235253
http://www.example.com/videos/search/hudsucker+proxy  
		    

但是这些页面会有怎样的外观呢?你需要为每一个action定义一个view-你可以在下一章里找到具体的内容,但在本章继续我们的controller-接下来的小节将会告诉你怎样利用Cake的controller的威力并且怎样发挥其优势。具体的说,你会学到怎样用你的controller传递数据给view,怎样重定向用户,以及更多的功能。

Section 1 Controller的方法

尽管本小节会介绍Cake模型中大多数频繁使用的方法,但也请记住 http://api.cake.org 可以获得完整的API参考。


与你的view进行交互

set
    string $var
    mixed $value
	   

这个方法是你的view从controller得到数据的主要方法。你可以用它传递任何数据:单一变量值,整个数组,等等。一但调用了set(),相应的变量就可以在view里访问到了:在controller里调用set(‘color’, ‘blue’)使得变量$color在view里变得可用了。

validateErrors
	   

返回在一次不成功的保存中生成的错误个数。

validate
	   

根据一个model预定义的有效性规则验证该model的数据。关于数据验证的的更多内容,请参见第11章。

render
    string $action
    string $layout
    string $file
	   

你也许不会经常使用这个方法,因为render方法是在controller action结束时自动被调用的,输出按action名字命令的view。同时,你也可以在controller逻辑里的任意位置调用来这个方法输出视图。


用户重定向

redirect
    string $url
	   

通过此方法告诉你的用户应该继续访问什么地方。这里传入的URL参数可以是一个Cake内部URL,也可以是一个完整的URL(http://...)。

flash
    string $message
    string $url
    int $pause
	   

该方法将在你的flash页面(该页面位于app/views/layouts/flash.tHTML)上显示提示信息[$message],停顿时间若干[$pause]秒,然后重定向用户到指定的Url[$url]。 Cake的redirect()和flash()方法并不包含exit()的调用。如果你希望自己的应用程序在redirect()或flash()之后停止继续执行,你需要自己在这些方法之后立即调用exit()。你也可能想要return()而不是exit(),依你的具体情况而定(例如,你需要执行某些回调)。


controller中的回调函数

Cake的controller特别提供了许多回调方法,你可以用它们在一些重要的controller方法之前或者之后插入一些逻辑。如果要利用这些功能,请在你的controller中用这里描述的参数和返回值定义这些方法。

beforeFilter  
        

在每个controller action调用前执行。它是一个检查当前sessoin状态和检查用户角色的好地方。

afterFilter
       

在每个controller action调用后执行。

beforeRender
       

在controller逻辑之后,并且在输出视图之前被调用。


其他有用的方法

尽管这些方法是Cake的Object类的一部分,他们在controller里仍然可用。

requestAction
    string $url
    array $options
       

这个方法可以在任意位置调用某个controller的action并且返回render后的视图。$url是一个Cake URL(/controllername/actionname/params)。如果$extra(译注:该方法里并没有出现$extra参数,这里是不是应该为$options?)数组包含’return’,这个action的AutoRender将会自动被设置为true。 你可以用requestAction从另一个controller action获取数据,也可以从另一个controller获取整个输出后的视图。
首先,从一个controller获取数据是很简单的。你只需在需要数据的地方使用requestAction方法。

设想我们需要创建一个简单的表格来显示系统里的用户。我们不用在另一个controller里重复编码,而只需要用requestAction()来调用UsersController::getUserList()就能得到用户数据。

如果在你的程序里,有一个频繁使用而又非静态的html元素(element),你也许会想使用requestAction()来将它插入到任意view里边。实际上我们不只是想要从UsersController::getUserList获取数据,还想要在另一个controller里边render这个action的view(这个view也许已包含了表格)。这样的方式可以避免重复编写view的代码。

请注意这里用requestAction()调用的action用的是一个空的布局(layout)-这样的话你就不必担心布局与布局之间嵌套带来的麻烦了。
在使用AJAX的情况下,当在一个AJAX调用之前或调用中间想从一个view生成一个html元素,requestAction()方法也是很有用的。

log
    string $message
    int $type = LOG_ERROR
       

你可以使用这个方法来记录web应用程序里发生的不同事件。所有生成的log可以在Cake的/tmp目录下找到。
如果$type的值为PHP常量LOG_DEBUG,消息将作为debug信息被写入log。对于其他任何值,消息作为error信息被写入log。

postConditions
    array $data
       

一个你可以用其将传入的$this->data格式化成model条件数组(conditions array)的方法。
例如,你有一个人员搜索表单:

// app/views/people/search.thtml:

提交包含这个元素的表单将会产生以下$this->data数组:

Array
(
    [Person] => Array
        (
            [last_name] => Anderson
        )
)
       

在这里,我们就可以用postConditions()来格式化这些数据以便于在model里使用:

Section 2 controller变量

在你的controller里利用一些特殊的变量可以发挥一些额外的Cake功能:

$name
PHP 4 返回的类名并不遵循CamelCase(驼峰命名法)格式。如果你因此遇到了问题,使用这个变量来为你的类设置正确的遵循CamelCase格式的名字。(译注:对于UsersController类,默认情况下Cake将通过CamelCase格式将”UsersController”拆分成”Users”和”Controller”,并以此来定位到与之对应的UserModel,而php 4下面返回很可能是userscontroller(不符合CamelCase),所以导致了问题)

$uses
你的controller会使用多个model吗?你的FragglesControllers会自动载入$this->Fraggle,但如果你还想访问$this->Smurf,尝试在你的controller里添加类似以下的代码:

注意:你仍然需要在$uses数组里包含你的Fraggle model,即使在这之前它(Fraggle model)就已经自动可用了。

$helpers
使用这个变量来让你的controller在view里边装载helper。HTML helper是自动被读取的,但是你可以用这个变量来指定其他的helper:

记住你仍然需要在$helpers数组里包含Html helper如果你想要使用它。它(Html helper)在默认情况下是可用的,但如果你定义了$helpers而没有指定它,系统将在view里边显示错误信息。

$layout
设置该变量的值为你想为这个controller使用的layout(布局)的名字。

$autoRender
将这个变量设为false能让action在自动render之前自动停止。

$beforeFilter
如果你想要一些代码在每次action被调用的时候执行(并且在该action任何代码运行之前),使用$beforeFilter。这个功能用来访问控制是非常完美的-你可以在任何action执行之前检查当前用户的权限。只要将这个变量设置成一个数组,该数组包含了你想要运行的controller action(在其他action运行之前执行的action)。

$components
就像$helpers和$uses一样,这个变量用来装载你需要的组件:

var $components = array('acl');

Section 3 controller 参数

在你的Cake controller里,你可以通过$this->params来访问controller的参数。这个变量用来获取传递到controller的数据,以及提供对当前请求信息的访问。$this->params最常见的用法是用于访问客户端通过POST或者GET操作递交给controller的信息。

$this->data
用来处理来自HTML helper的POST表单数据。

$this->params[‘form’]
来自任何表单的POST数据都储存在这里,包括$_FILES里的信息。

$this->params[‘bare’]
如果当前布局是bare返回’1’,否则返回’0’。

$this->params[‘ajax’]
如果当前布局是ajax返回’1’,否则返回’0’。

$this->params[‘controller’]
返回处理该请求的当前controller的名字。例如,如果URL /posts/view/1被调用,$this->params[‘controller’]的值应该是’posts’。

$this->params[‘action’]
返回处理该请求的当前action的名字。例如,如果URL /posts/view/1被调用,$this->params[‘action’]的值应该是view。

$this->params[‘pass’]
返回当前请求传入的GET查询字符串。例如,如果URL URL /posts/view/?var1=3&var2=4被调用,$this->params[‘pass’]应该等于"?var1=3&var2=4"。

$this->params[‘url’]
返回当前被请求的URL,连同get参数的键值对一起。例如如果/posts/view/?var1=3&var2=4被调用,$this->params[‘url’]应该是以下内容: