5

概括:

缓存期间是否执行预控制器挂钩?是否有任何会执行的挂钩点?(预系统?

我可能应该强调钩子不会影响发送到浏览器的内容这一事实。那不是问题。


详细版本:

我计划在我使用 PHP 和 CodeIgniter 构建的项目中实现一些统计类型的功能。

有问题的项目是定制的 CMS - 由于更新之间的间隔延长,我使用缓存来帮助加快加载时间;这不是必需的,但它是优先的。对于大部分静态站点来说,这似乎是一个很好的解决方案;特别是在动态内容主要在客户端提供服务的情况下 - 即 AJAX 请求。

提议的功能主要涉及一个预控制器挂钩,该挂钩通过诸如用户代理库之类的库访问方法,然后将它们转储到数据库中。从这里它可以被轮询,通过 JSON 输出并在被 jQuery flot 插件之类的东西显示之前进行操作。

我已经阅读了有关Web Page Caching的文档以及有关 hooks的文档。不幸的是,目前尚不清楚使用缓存是否会完全绕过钩子。

我知道cache_override这意味着实现你自己的缓存机制;不是我想做的!

另一种方法是在客户端收集统计信息并通过 AJAX 将其提交给服务器;但这也不理想,因为我试图明确分离逻辑 - 出于维护和测试的原因。

4

1 回答 1

10

简而言之:

  • 缓存期间是否执行预控制器挂钩?没有
  • 是否有任何会执行的挂钩点? pre_system的确实执行。

如果缓存在system/core/CodeIgniter.php:189开始,唯一有机会运行的钩子是pre_system(system/core/CodeIgniter:124)

不幸的是,此时您并没有获得太多 codeigniter 的功能,没有get_instance()也没有加载大多数核心库。如果你愿意,你可以看看里面定义了哪些函数,system/core/Common.php这几乎就是你所拥有的。

如果您真的想使用内置类来完成这项工作,您可以通过自己的方式获得数据库对象和其他类似这样的核心内容:

  1. 您将不得不手动获取BASEPATH.'database/DB.php'包含在其中的文件。幸运的是,在加载器类中,它加载了它,require_once因此它不会在缓存未命中时破坏页面。
  2. 一旦你Database加载了库,就$this->db调用调用来实例化通常的对象DB()。如果没有参数,它将照常从配置文件中加载默认数据库。
  3. 此时,您可以从pre_system钩子中编写查询,并且由于钩子可以是对象,因此您可以将每个日志记录代码移动到钩子的对象中。如果您需要其他库,您可以使用该函数获取它们的实例(如果您没有加载内置类,load_class()请不要忘记将第三个前缀参数设置为空字符串)。

最后你应该像这样结束(虚构代码):

class MyLoggingHook {
    // called from the hook config
    public function run($params = array()) {
        require_once(BASEPATH.'database/DB.php');
        $db = DB(); // getting hold of a DAO instance

        // routing information is always useful to have for pageview logs
        $RTR = load_class('Router', 'core');
        $RTR->_set_routing();
        // Router also load Uri and Config classes inside so the following two instances could be interesting too:
        // $RTR->uri 
        // $RTR->config

        // load some useful library not related to CodeIgniter
        $user_agent_detector = load_class('UserAgentDetector', 'libraries', '');

        // do some logging
        $db->insert('page_view_log', array('class' => $RTR->fetch_class(), 'method' => $RTR->fetch_method(), /*...*/);
    } 
}

我可能应该提一下,我从来没有在生产中使用过这样的东西,并且存在可能会因版本而异的功能传递的风险。如果你可以在不接触钩子内的 Codeigniter 类的情况下做到这一点。

使用PDO进行数据库访问,使用 加载数据库配置get_config(),您无需接触任何与 codeigniter 相关的类即可。

于 2012-12-07T23:10:57.133 回答