【问题标题】:Why does codeigniter database cache regenerates file?为什么codeigniter数据库缓存会重新生成文件?
【发布时间】:2014-09-25 17:22:21
【问题描述】:

我使用 Codeigniter 数据库缓存已经有一段时间了,它工作得很好,但现在我遇到了一个特定查询的奇怪问题。步骤如下:

  1. 我的缓存目录是空的。
  2. 我打开 URL /myproject/mycontroller/myaction/
  3. 文件缓存在 mycontroller-myaction 目录中(我用记事本打开文件以确保它包含正确的数据。
  4. 我再次打开 /myproject/mycontroller/myaction/ 期望从缓存中检索数据,结果发现数据是从数据库中检索的,并且重新生成了文件。我不知道为什么,但关键是生成的文件没有用。

如果对你很重要,我会给你下一个信息:

  • 查询是一个存储过程。
  • 我还有其他运行良好的查询。

非常感谢您的帮助,如果您需要具体数据,请告诉我。

谢谢。

使用 xdebug 我发现在查询函数的 DB_driver.php 文件中,第 277 行有一个条件如下:

// Is query caching enabled?  If the query is a "read type"
    // we will load the caching class and return the previously
    // cached query if it exists
    if ($this->cache_on == TRUE AND (stristr($sql, 'SELECT')))
    {
        if ($this->_cache_init())
        {
            $this->load_rdriver();
            if (FALSE !== ($cache = $this->CACHE->read($sql)))
            {
                return $cache;
            }
        }
    }

查询必须是 SELECT,我使用的是存储过程,我的模型是:

public function cobertura($param1= NULL) {
        $query = $this->db->query("[SP_NAME] ?", array($param1));
    }

    return $query->result();
}

所以当我使用存储过程而不是 SELECT 语句时,条件返回 FALSE 并再次生成缓存文件。

如何修改该函数以将我的存储过程检测为有效语句?

非常感谢。

【问题讨论】:

  • 嗨,你能把你的代码贴在你的控制器上吗?
  • @PinoyPal,我添加了有用的信息,感谢您的宝贵时间。

标签: sql-server database codeigniter caching stored-procedures


【解决方案1】:

好吧,这个问题的解决方案是修改这个

if ($this->cache_on == TRUE AND (stristr($sql, 'SELECT')))

通过这个

if ($this->cache_on == TRUE AND (stristr($sql, 'SELECT') OR strpos($sql, '[')))

这样我告诉 CI,当我的 sql 语句以 [ 开头时,也是一个 SELECT 查询。

当我有一个不是选择语句的存储过程时,只需禁用缓存。

如果你有更好的解决方案可以分享。

【讨论】:

    【解决方案2】:

    您不应该在 CodeIgniter 中使用查询缓存。除非您确切知道自己在做什么,否则使用它是不安全的。

    相反,我会创建一个 cacheQuery 函数或类似的函数,至少让您可以控制查询的缓存。任何返回数据或可能返回数据的查询都可以被缓存的假设是非常冒险的。

    通过替换 CI 尝试的自动化并手动执行,您还将获得一些速度。如果您 xdebug profile 所有猜测 CI 对您的查询所做的一切都会给查询函数增加很多开销。

    上面发布的解决方案也可能有点狡猾,因为并非所有存储过程都返回数据,并且方括号可能位于查询中的任何位置,因此检查可能会出错。如果第一个字符返回 false,如果字符在查询中的任何位置,则返回 true,即使它不构成存储过程。例如,DELETE FROM table1 WHERE column1="[xxx]"。

    这种东西 stristr($sql, 'SELECT') 和 strpos($sql, '[') 不好。 CodeIgniter 简单、整洁、一致且组织良好,但其中 PHP 代码的实际质量极差。公平地说,这部分是因为它与旧版本的 PHP 保持兼容性,但有几件事是莫名其妙的糟糕。对于这类事情,CodeIgniter 的政策是“如果它在 90% 或更多的时间里都有效,那就没问题”。这当然不适合大型严肃的企业应用程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      相关资源
      最近更新 更多