CodeIgniter:所有$ this-> db-> query()方法调用的SQL审计?

时间:2011-10-25 18:25:20

标签: php mysql codeigniter audit

我正在使用CodeIgniter 2+并希望审核所有$this->db->query($sql);次来电。

我们所有的数据库调用都是通过query()方法;没有活动记录使用。我需要记录$ sql查询并将它们输入到自定义表中以进行审计记录。有没有人知道扩展核心系统数据库库以审计查询的方法?

看起来这应该很容易,但我似乎无法找到一个简单的解决方案。 CI论坛有几篇关于旧版本的失败帖子。

3 个答案:

答案 0 :(得分:5)

这取决于您希望如何审核它们。如果您要查找每页,那么启用分析器就可以了。这显示了在该页面加载上运行的所有查询以及执行它们所花费的时间。请参阅以下有关分析器的链接。

http://codeigniter.com/user_guide/general/profiling.html

如果您希望在发生所有查询时将其记录下来,然后再阅读日志文件,则必须扩展数据库类。如果是这种情况,请发表评论并进一步更新/扩展我的答案。

扩展为覆盖query()

在/ application / core /中扩展MY_Loader.php并插入此函数

function database($params = '', $return = FALSE, $active_record = NULL)
    {
        // Grab the super object
        $CI =& get_instance();

        // Do we even need to load the database class?
        if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db)) {
            return FALSE;
        }

        require_once(BASEPATH.'database/DB'.EXT);

        // Load the DB class
        $db =& DB($params, $active_record);

        $my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_driver';
        $my_driver_file = APPPATH.'core/'.$my_driver.EXT;

        if (file_exists($my_driver_file)) {
            require_once($my_driver_file);
            $db = new $my_driver(get_object_vars($db));
        }

        if ($return === TRUE) {
            return $db;
        }

        // Initialize the db variable.  Needed to prevent
        // reference errors with some configurations
        $CI->db = '';
        $CI->db = $db;
    }

然后创建/application/core/MY_DB_mysql_driver.php

然后在里面你可以覆盖query()

function query($sql, $binds = FALSE, $return_object = TRUE) {
    // Do your stuff
    return parent::query( $sql, $binds, $return_object );
}

显然将文件名中的mysql替换为您正在使用/尝试扩展的数据库驱动程序。

这也适用于Active Record,因为所有get()方法都会从驱动程序调用{​​{1}}来运行查询。

答案 1 :(得分:3)

如果你只想直接这样做......

查询功能位于system / database / DB_driver.php第250行(根据您的版本而定)。

在第289行附近有一条评论说“运行查询”。

此时以您喜欢的任何方式输出$sql

答案 2 :(得分:3)

您似乎可以扩展数据库类并覆盖query方法,但是according to Phil,无法完成。

一种解决方案是创建一个帮助方法,您可以使用该方法替换所有$this->db->query调用,然后调用查询,然后调用query方法。

<强>更新

您可以创建一个复制Profiler库的_compile_queries方法的库(https://github.com/EllisLab/CodeIgniter/blob/develop/system/libraries/Profiler.php的第168行)。通常,此方法会将所有查询输出到浏览器,但您可以以记录所有查询的方式实现它。然后,您不仅会获得使用$this->db->query生成的查询,而且还会运行所有查询。