2010-04-08 109 views
7

Wordpress附帶wpdb類處理CRUD操作。我感興趣的這個類的兩種方法是insert()(CRUD中的C)和update()(CRUD中的U)。Wordpress數據庫插入()和更新() - 使用NULL值

當我想向MySQL數據庫列中插入NULL時出現問題--類將PHP空變量轉義爲空字符串。我如何告訴Wordpress使用實際的MySQL NULL而不是MySQL字符串?

回答

8

如果你想要它兼容,你將不得不顯示COLUMN並且如果允許NULL,則提前確定。如果允許,那麼如果該值爲空($ v),則在查詢中使用val = NULL。

$foo = null; 
$metakey = "Harriet's Adages"; 
$metavalue = "WordPress' database interface is like Sunday Morning: Easy."; 

if ($foo == null) { 
$wpdb->query($wpdb->prepare(" 
    INSERT INTO $wpdb->postmeta 
    (post_id, meta_key, meta_value, field_with_null) 
    VALUES (%d, %s, %s, NULL)", 
     10, $metakey, $metavalue)); 
} else { 
$wpdb->query($wpdb->prepare(" 
    INSERT INTO $wpdb->postmeta 
    (post_id, meta_key, meta_value, field_with_null) 
    VALUES (%d, %s, %s, %s)", 
     10, $metakey, $metavalue, $foo)); 
} 
+0

我創建的表作爲自定義的一部分插件 - 有問題的列確實接受NULL值。 – leepowers 2010-04-08 07:19:09

+0

@ pygorex1 - 這是怎麼回事? – 2010-04-08 19:37:40

+0

除了改變插件的NULL /空語義以外,這幾乎是唯一的解決方案。 – leepowers 2010-05-03 23:36:25

4

這是您的問題的解決方案。在「的wp-content」文件夾中創建一個名爲「db.php中」文件,並把這個代碼在它:

<?php 

// setup a dummy wpdb to prevent the default one from being instanciated 
$wpdb = new stdclass(); 

// include the base wpdb class to inherit from 
//include ABSPATH . WPINC . "/wp-db.php"; 


class wpdbfixed extends wpdb 
{ 
    function insert($table, $data, $format = null) { 
     $formats = $format = (array) $format; 
     $fields = array_keys($data); 
     $formatted_fields = array(); 
     $real_data = array(); 
     foreach ($fields as $field) { 
      if ($data[$field]===null) 
      { 
       $formatted_fields[] = 'NULL'; 
       continue; 
      } 
      if (!empty($format)) 
       $form = ($form = array_shift($formats)) ? $form : $format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 
      $formatted_fields[] = "'".$form."'"; 
      $real_data[] = $data[$field]; 
     } 
     //$sql = "INSERT INTO <code>$table</code> (<code>&quot; . implode('</code>,<code>', $fields) . &quot;</code>) VALUES (" . implode(",", $formatted_fields) . ")"; 
     $sql = "INSERT INTO $table (" . implode(',', $fields) . ") VALUES (" . implode(",", $formatted_fields) . ")"; 
     return $this->query($this->prepare($sql, $real_data)); 
    } 

    function update($table, $data, $where, $format = null, $where_format = null) 
    { 
     if (!is_array($where)) 
      return false; 

     $formats = $format = (array) $format; 
     $bits = $wheres = array(); 
     $fields = (array) array_keys($data); 
     $real_data = array(); 
     foreach ($fields as $field) { 
      if ($data[$field]===null) 
      { 
       $bits[] = "$field = NULL"; 
       continue; 
      } 
      if (!empty($format)) 
       $form = ($form = array_shift($formats)) ? $form : $format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 
      $bits[] = "$field = {$form}"; 

      $real_data[] = $data[$field]; 
     } 

     $where_formats = $where_format = (array) $where_format; 
     $fields = (array) array_keys($where); 
     foreach ($fields as $field) { 
      if (!empty($where_format)) 
       $form = ($form = array_shift($where_formats)) ? $form : $where_format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 
      $wheres[] = "$field = {$form}"; 
     } 

     $sql = "UPDATE $table SET " . implode(', ', $bits) . ' WHERE ' . implode(' AND ', $wheres); 

     return $this->query($this->prepare($sql, array_merge($real_data, array_values($where)))); 
    } 

} 

$wpdb = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST); 
?> 

這樣你可以使用空值 WPDB用!

0

我試圖編輯這裏列出的其他解決方案之一,因爲它導致格式數組與數據數組錯位,但失敗。

下面是修改從WordPress的最新版本的WPDB,爲了讓使用insert()和update()插入和更新空值的SQL表的解決方案:

/* 
* Fix wpdb to allow inserting/updating of null values into tables 
*/ 
class wpdbfixed extends wpdb 
{ 
    function insert($table, $data, $format = null) { 
     $type = 'INSERT'; 
     if (! in_array(strtoupper($type), array('REPLACE', 'INSERT'))) 
      return false; 
     $this->insert_id = 0; 
     $formats = $format = (array) $format; 
     $fields = array_keys($data); 
     $formatted_fields = array(); 
     foreach ($fields as $field) { 
      if (!empty($format)) 
       $form = ($form = array_shift($formats)) ? $form : $format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 

      //***Steve Lee edit begin here*** 
      if ($data[$field]===null) { 
       unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted. 
       $formatted_fields[] = 'NULL'; 
      } else { 
       $formatted_fields[] = $form; //Original line of code 
      } 
      //***Steve Lee edit ends here*** 
     } 
     $sql = "{$type} INTO `$table` (`" . implode('`,`', $fields) . "`) VALUES (" . implode(",", $formatted_fields) . ")"; 
     return $this->query($this->prepare($sql, $data)); 
    } 

    function update($table, $data, $where, $format = null, $where_format = null) 
    { 
     if (! is_array($data) || ! is_array($where)) 
      return false; 

     $formats = $format = (array) $format; 
     $bits = $wheres = array(); 
     foreach ((array) array_keys($data) as $field) { 
      if (!empty($format)) 
       $form = ($form = array_shift($formats)) ? $form : $format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 

      //***Steve Lee edit begin here*** 
      if ($data[$field]===null) 
      { 
       unset($data[$field]); //Remove this element from array, so we don't try to insert its value into the %s/%d/%f parts during prepare(). Without this, array would become shifted. 
       $bits[] = "`$field` = NULL"; 
      } else { 
       $bits[] = "`$field` = {$form}"; //Original line of code 
      } 
      //***Steve Lee edit ends here*** 
     } 

     $where_formats = $where_format = (array) $where_format; 
     foreach ((array) array_keys($where) as $field) { 
      if (!empty($where_format)) 
       $form = ($form = array_shift($where_formats)) ? $form : $where_format[0]; 
      elseif (isset($this->field_types[$field])) 
       $form = $this->field_types[$field]; 
      else 
       $form = '%s'; 
      $wheres[] = "`$field` = {$form}"; 
     } 

     $sql = "UPDATE `$table` SET " . implode(', ', $bits) . ' WHERE ' . implode(' AND ', $wheres); 
     return $this->query($this->prepare($sql, array_merge(array_values($data), array_values($where)))); 
    } 

} 
global $wpdb_allow_null; 
$wpdb_allow_null = new wpdbfixed(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST); 

插入這段代碼進入總是運行的地方,比如你的functions.php,然後像正常一樣使用新的全局$ wpdb_allowed_null-> insert()和 - > update()。

我更喜歡這種方法,而不是重寫默認的$ wpdb,以保留其他Wordpress和其他插件所期望的數據庫行爲。

1

我在Wordpress StackExchange論壇上找到這個,它對我很好。

// Add a filter to replace the 'NULL' string with NULL 
add_filter('query', 'wp_db_null_value'); 

global $wpdb; 
$wpdb->update(
    'table', 
    array( 
     'status' => 'NULL', 
    ), 
    array('id' => 1) 
); 

// Remove the filter again: 
remove_filter('query', 'wp_db_null_value'); 

和功能wp_db_null_value是:

/** 
* Replace the 'NULL' string with NULL 
* 
* @param string $query 
* @return string $query 
*/ 

function wp_db_null_value($query) 
{ 
    return str_ireplace("'NULL'", "NULL", $query); 
} 

因爲在我的情況下,我不能用$ DB->準備()函數...

+0

最好的解決方案是! – 2015-04-16 17:37:42

相關問題