0

requestAction主要是在 CakePHP 中用于渲染应该在所有应用程序的页面上或最初没有找到的地方。

例如:在网站每个页面的页脚显示注册用户总数。

在 requestAction 方法中,这可以通过请求返回模型用户计数的 UsersController 的操作来完成。让我们将其命名为 usersCount()。此请求应位于此应用程序视图使用的布局中。

在我建议的方法中,这可以通过使用 AppControler 中的 User 模型然后为用户计数设置一个变量来完成,应该在所有布局和视图中都可用,例如

//in AppController

function beforeRender(){
  $this->uses = array('Model', 'User');
  $this->set('totalUsers',$this->User->find('count'));
}

因此,在任何布局、视图或元素中,我们都可以轻松使用 $totalUsers 值

<div class="footer">Currently, we have <?php echo $totalUsers;?> registered users.</div>

这里的“更好”一词是指性能。这两种方法中哪一种在性能上更好?

4

1 回答 1

2

轮廓

每当对几种可能性的相对表现有疑问时,不要依赖其他人的建议(这可能是纯粹的猜测):profile

DebugKit带有一个Benchmark shell,它是一种生成基准信息的便捷方式(seigeab是两个更准确/可靠的替代方案):

$ cd my/app
$ Console/cake DebugKit.benchmark
Allows you to obtain some rough benchmarking statistics about a fully
qualified URL.

Usage:
cake debug_kit.benchmark [-h] [-v] [-q] [--n 10] [--t 100] <url>

Options:

--help, -h     Display this help.
--verbose, -v  Enable verbose output.
--quiet, -q    Enable quiet output.
--n            Number of iterations to perform. (default:
            10)
--t            Maximum total time for all iterations, in seconds.If a
            single iteration takes more than the tiemout, only one request will be
            made (default: 100)

Arguments:

url  The URL to request.

Example Use: `cake benchmark --n 10 --t 100 http://localhost/testsite`.
Note: this benchmark does not include browser render times.

使用这样的工具将解决大多数关于性能的疑问 - 只需设置几个控制器操作并注意每个操作的相对性能。

为什么要限制自己有两种可能性?

让我们假设问题不在于使用 requestAction 是否比总是填充可能不会使用的变量更好(提示),而是:在所有/大多数页面上显示 <something> 的最佳方式是什么

这里有两条简单的规则,可能可以解决大多数问题:

  1. 使用缓存
  2. 不要索要您不会使用的数据/仅在您将要使用时才索取数据

在某些方面,提出的两个选项requestAction中更合适 - 但还有其他选项可以达到与给出的示例相同的结果。

元素缓存

而不是总是(一种或另一种方式)获取数据 - 获取一次并且在数据陈旧之前不要再次获取它。例如,在布局中使用元素缓存,以便元素中的任何内容都不会在每个请求上执行:

echo $this->element(
    'footer',
    array(),
    "cache" => array('config' => 'element_config', 'key' => 'footer')
);

元素的内容footer应该是自给自足的,例如:

<?php
$User = ClassRegistry::init('User');
// $betterExample = $User->expensiveCall(); // more relevant where the call is slow
$totalUsers = $User->find('count');
?>
<div class="footer">Currently, we have <?php echo $totalUsers;?> registered users.</div>

这样,只有在没有缓存结果时才请求元素的数据。通过调整相关的缓存配置(适当的缓存配置取决于要求 - 需要或多或少是实时的?使用例如 30 秒的缓存配置;是否过时无关紧要?使用 1 天),计数器的频率可以修改更新。

或者,可以使用无限缓存时间,而是仅在值更改时才清除缓存:

class User extends AppModel {

    public function updateCounterCache($keys = array(), $created = false) {
        Cache::delete('footer', 'element_config');
        return parent::updateCounterCache($keys, $created);
    }
}

其他技术?

还有其他类似的技术可以使用(包括将元素与 结合使用requestAction) - 但原则始终相同:不要急于执行可能不需要的逻辑(获取数据),有效地使用缓存。

于 2013-10-26T19:07:34.283 回答