2011-06-01 61 views
1

我有一個擴展了mysqli的類,以便記錄查詢。使用查詢日誌記錄擴展mysqli,但不會丟失insert_id

不幸的是,我想不出如何不失去insert_id財產。

我希望能夠做到這一點

$sql = sprintf(" 
    INSERT INTO picture 
    SET  nm_picture = '%s' 

", 
    Db::instance()->escape_string($_POST['nm_picture']) 
); 

$result = Db::instance()->queri($sql); 
$id_inserted_pic = Db::instance()->insert_id; 

$id_inserted_pic是activity_log ID。

我希望我能夠覆蓋$this->insert_id,但唉。

任何幫助表示讚賞。

我的代碼,因爲它代表爲了簡明,刪除了幾個位: (請注意,有些是別人編寫和/或可能不理想)

class Db extends \mysqli 
{ 
    private static $instance; 
    protected $_database; 

    public $insert_id; /* doesn't error but doesn't work either */ 

    private function __construct(array $config) 
    { 
     if (
      is_array($config) 
      && isset($config['host']) 
      && isset($config['username']) 
      && isset($config['password']) 
      && isset($config['database']) 
     ) 
     { 
      $this->_database = $config['database']; 
      parent::__construct(
       $config['host'] 
       , $config['username'] 
       , $config['password'] 
       , $config['database'] 
       , $config['port'] 
       , $config['socket'] 
      ); 
     } 
    } 

    /** 
    * Singleton Pattern 
    * @param array $config 
    */ 
    public static function instance(array $config = null) 
    { 
     if (!isset(self::$instance)) { 
       $c = __CLASS__; 
       self::$instance = new $c($config); 
      } 
      return self::$instance; 
    } 

    /** 
    * Save the passed string into the activity_log table 
    * 
    * @param string $query 
    * @param bool $force default false 
    */ 
    public function activity_log($query, $force = false) 
    { 
     $sql = sprintf(' 
      INSERT INTO sw_activity_log 
      SET  tx_activity_log = "%s" 
     ', 
      $query 
     ); 
     $result = $this->query($sql); 

     if ($result !== false) 
     { 
      return $result; 
     } 
     else 
     { 
      //... 
     } 
    } 

    /** 
    * Run a query and activity_log() it if matched and not told otherwise 
    * 
    * @param string $query 
    * @param unknown_type $resultmode 
    * @param bool|null $fl_log default null 
    * 
    * @return mysqli_result; 
    */ 
    public function queri($query, $resultmode = null, $fl_log = null) 
    { 
     $result = parent::query($query, $resultmode); 
     $tmp_insert_id = $this->insert_id; 

     if ($result !== false) 
     { 
      if ($fl_log || ($fl_log !== false && preg_match('~^(\s+)?(REPLACE|INSERT|DELETE|UPDATE)~ims', $query) > 0)) 
      { 
       self::activity_log($query); 
      } 
      $this->insert_id = $tmp_insert_id; 
      return $result; 
     } 
     else 
     { 
      // ... 
     } 
    } 
} 

回答

1

你有兩種可能性:

  • 不要在活動日誌使用自動遞增。真的不需要它。在該表中甚至不需要主鍵,導致您將要連接的是什麼?
  • 在實際查詢之前插入活動日誌,將所有內容包含在事務中,並在查詢無效時進行回滾。
+0

這兩個建議都很棒!我可能會做後者。謝謝。 – jezmck 2011-06-01 15:19:55

2

我建議有您的方法將插入ID保存在類變量中的某處。使日誌記錄功能設置一個標誌變量,告訴方法在執行日誌查詢時不存儲插入ID。這樣你就可以從最後一次非日誌插入中保留插入ID。

+0

這和我已經做的非常相似,我希望能夠使用$ this-> insert_id,所以我不必改變現有的代碼。 – jezmck 2011-06-01 14:20:50