2011-10-25 41 views
4

我正在使用CodeIgniter 2+並希望審覈所有$this->db->query($sql);調用。

我們所有的數據庫調用都是通過query()方法;沒有活動的記錄用法。我需要記錄$ sql查詢並將它們輸入到自定義表中以用於審計記錄目的。是否知道將核心系統數據庫擴展到審計查詢的方式?

這似乎應該很容易,但我似乎無法找到一個簡單的解決方案。 CI論壇有幾個關於舊版本的故障帖子。

+1

如果您有權訪問服務器,可以嘗試使用MySQL內置的[query logging](http://dev.mysql.com/doc/refman/5.1/en/query-log.html)。 –

+0

火箭,好主意。但是,我們將來可能會轉換到MS SQL或Oracle。我正在尋找一個基於PHP的解決方案。 – jjwdesign

+0

啊,好的。只是一個想法:-) –

回答

5

這取決於你想要如何審計它們。如果你正在尋找每個頁面的基礎,然後啓用分析器將會很好。這顯示了在該頁面上運行的所有查詢以及執行它們所花費的時間。請參閱探查器上的以下鏈接。

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

如果您正在尋找記錄所有的查詢,因爲它們發生,再後來讀日誌文件,你將不得不擴展數據庫類。如果是這樣,評論和我會進一步更新/延長我的答案。

延伸至覆蓋query()

在/應用/核心擴展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

然後那裏面你可以覆蓋查詢()

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

顯然將文件名中的mysql替換爲您正在使用/嘗試擴展的任何數據庫驅動程序。

這也將與活動記錄一起使用,因爲所有get()方法都會從驅動程序調用query()來運行其查詢。

+1

我還沒有使用分析庫。我需要審查(記錄)發生的查詢(不是最後)並將每個查詢保存爲數據庫表中的條目。我不確定Profiler能夠幫助我做到這一點。 – jjwdesign

+0

這給了我一個想法。我已經根據這個更新了我的答案。 – swatkins

+0

更新了我的答案,解釋瞭如何在不觸及核心的情況下覆蓋數據庫驅動程序類。 –

3

如果你只是想這樣做,直接...

查詢功能在系統/數據庫/ DB_driver.php線250(左右取決於您的版本)。

有一個評論,說你喜歡在這一點任何方式「運行查詢」,在大約289線

輸出$sql

+3

+1 - 覆蓋核心是不是一個好主意,但由於你不能擴展db類,這可能無需重寫已有的代碼即可成爲最佳解決方案。 – swatkins

+0

Ecckkkk sppppp,我不想改變核心代碼。 – jjwdesign

+1

在我看來,codeigniter很好但不是很好。沒有理由不遵守你的意願。也就是說,另一種方法是使用所有其他擴展的自定義模型類。他們都調用一個調用'$ this-> db-> query()'的父方法。完成後,您可以調用'$ this-> db-> last_query()'並記錄它。或者你可以有SQL層日誌查詢。 – evan

3

看來您可以擴展數據庫類並覆蓋query方法,但according to Phil,它不能完成。

一個解決方案是創建一個幫助器方法,您可以將所有的$this->db->query調用替換爲記錄您的查詢的調用,然後調用query方法。

UPDATE

您可以創建一個庫,複製探查庫(線https://github.com/EllisLab/CodeIgniter/blob/develop/system/libraries/Profiler.php 168)的_compile_queries方法。通常情況下,此方法會將所有查詢輸出到瀏覽器,但您可以通過記錄所有查詢的方式來實現它。那麼,您不僅會得到使用$this->db->query生成的查詢,而且還會運行所有查詢。