3.5.3.4 其他有用的方法

3.5.3.4.1 constructClasses

该方法加载控制器需要的模型(model)。该加载过程通常由CakePHP控制,不过该方法也适用于那些从特定函数进行控制器访问的情况。比如你需要在命令行脚本或者其他地方使用CakePHP的时候,constructClasses()可能会帮上你的忙。

3.5.3.4.2 referer

返回当前请求的参照页面的URL。

3.5.3.4.3 disableCache

该函数可以告知用户的浏览器不要缓存当前请求页面的内容。注意该缓存不同于下一章会提到的视图的缓存。

3.5.3.4.4 postConditions

postConditions(array $data, mixed $op, string $bool, boolean $exclusive)

该方法可以将接收到的POST的数据(与HtmlHelper相兼容的数据形式)转换成find方法可以使用的数据集。该方法对从POST数据快速建立搜索逻辑非常有效,比如,管理员需要查看订单以确定需要配送的货物的时候,可以利用CakePHP的Form和HtmlHelper创建一个基于订单(Order)的表单,然后在控制器的行为中使用POST得到的数据进行搜索:

function index() {
    $o = $this->Orders->findAll($this->postConditions($this->data));
    $this->set('orders', $o);
}
  1. function index() {
  2. $o = $this->Orders->findAll($this->postConditions($this->data));
  3. $this->set('orders', $o);
  4. }

如果$this->data['Order']['destination']"Old Towne Bakery"相等,postConditions就将这个条件转换成一个Model->findAll()能使用的条件数组。在这个例子中就是array("Order.destination" = > "Old Towne Bakery")

如果你想使用其他的SQL运算符,像下例一样,使用第二个参数。

/*
$this->data的内容
array(
    'Order' => array(
        'num_items' => '4',
        'referrer' => 'Ye Olde'
    )
)
*/

//查找至少有4件货物以及包含"Ye Olde"的订单
$o = $this->Order->findAll($this->postConditions(
    $this->data,
    array('>=', 'LIKE')
));
  1. /*
  2. $this->data的内容
  3. array(
  4. 'Order' => array(
  5. 'num_items' => '4',
  6. 'referrer' => 'Ye Olde'
  7. )
  8. )
  9. */
  10. //查找至少有4件货物以及包含"Ye Olde"的订单
  11. $o = $this->Order->findAll($this->postConditions(
  12. $this->data,
  13. array('>=', 'LIKE')
  14. ));

指定运算符的关键在于$this->data数组中字段的顺序。由于num_items在第一位,于是>=是应用于该字段的。

第三个参数允许你告诉CakePHP在这些条件之间使用什么逻辑运算符进行连接。这里可以使用"AND","OR",以及"XOR"等等。

最后,如果最后的参数被设为true,并且$op是一个数组,那么不包含在$op中的字段将不会被包含在返回的条件之中。

3.5.3.4.5 paginate

该方法用于将模型(model)取到的数据进行分页。可以设置每页显示的件数,查找的条件以及其他的选项。要查看更详细的信息请参阅pagination

3.5.3.4.6 requestAction

requestAction(string $url, array $options)

该方法可以在任何位置调用控制器中的行为(action)并将行为中的数据返回。参数$url传递一个CakePHP形式的相对URL(/controllername/actionname/params)。如果需要传递数据给被调用的行为,请使用$options参数。

通过在options中指定'return'可以取到被渲染结束的视图数据:requestAction($url, array('return'));

在不使用缓存的情况下,requestAction可能会导致非常低下的性能。在控制器(controller)或者模型(model)这么使用是非常不合适的。

requestAction最适合用在(使用了缓存的)页面元素(element)的相关处理上,用于在渲染页面之前取得该元素需要的数据。假设有这么一个例子,我们需要在页面显示最近的评论这样一个页面元素。那么首先我们创建一个控制器的函数来返回这些数据。

// controllers/comments_controller.php
class CommentsController extends AppController {
    function latest() {
        return $this->Comment->find('all', array('order' => 'Comment.created DESC', 'limit' => 10));
    }
}
  1. // controllers/comments_controller.php
  2. class CommentsController extends AppController {
  3. function latest() {
  4. return $this->Comment->find('all', array('order' => 'Comment.created DESC', 'limit' => 10));
  5. }
  6. }

然后在页面元素中调用这个函数:

// views/elements/latest_comments.ctp

$comments = $this->requestAction('/comments/latest');
foreach($comments as $comment) {
    echo $comment['Comment']['title'];
}
  1. // views/elements/latest_comments.ctp
  2. $comments = $this->requestAction('/comments/latest');
  3. foreach($comments as $comment) {
  4. echo $comment['Comment']['title'];
  5. }

这样我们就可以把这个页面元素放到任何我们想要输出最近的评论的地方:

echo $this->element('latest_comments');
  1. echo $this->element('latest_comments');

采用这种写法的话,不管该页面元素什么时候被渲染输出,都会产生一个给控制器的请求,然后数据被处理加工,返回给页面元素。不过我们前面说了这不适合用来处理未被缓存的页面输出。所以我们稍微修改一下,变成这样:

echo $this->element('latest_comments', array('cache'=>'+1 hour'));
  1. echo $this->element('latest_comments', array('cache'=>'+1 hour'));

于是,在缓存的有效期内,requestAction不会被重复地执行。

另外,requestAction现在也可以接收cake风格的URL:

echo $this->requestAction(array('controller' => 'articles', 'action' => 'featured'), array('return'));
  1. echo $this->requestAction(array('controller' => 'articles', 'action' => 'featured'), array('return'));

这就允许requestAction的调用可以利用Router::url增加一定的性能。这种URL的格式与HtmlHelper::link所使用的基本一样。一点不同的是,如果你在URL中使用命名参数,那么requestAction的URL数组必须把这些参数用'named'作为key包(wrap)起来。这是因为requestAction只把命名参数数组与Controller::params的成员数组进行合并而不会把key为'named'的参数数组替换。

echo $this->requestAction('/articles/featured/limit:3');
  1. echo $this->requestAction('/articles/featured/limit:3');

写成数组形式的话:

echo $this->requestAction(array('controller' => 'articles', 'action' => 'featured', 'named' => array('limit' => 3)));
  1. echo $this->requestAction(array('controller' => 'articles', 'action' => 'featured', 'named' => array('limit' => 3)));
其他有用的方法 :: 控制器中的方法 :: 控制器(Controllers) :: 与CakePHP一起开发 :: CakePHP 手册 :: 1.2 Collection :: The Cookbook

CakePHP 手册

Table of Contents