2010-04-08 7 views
7

Tàu Wordpress có lớp wpdb xử lý các hoạt động CRUD. Hai phương pháp của lớp này mà tôi quan tâm là insert() (chữ C trong CRUD) và update() (chữ U trong CRUD).Chèn cơ sở dữ liệu Wordpress() và cập nhật() - sử dụng giá trị NULL

Sự cố xảy ra khi tôi muốn chèn NULL vào cột cơ sở dữ liệu mysql - lớp wpdb thoát biến PHP null thành chuỗi rỗng. Làm thế nào tôi có thể nói với Wordpress để sử dụng một thực tế MySQL NULL thay vì một chuỗi MySQL?

Trả lời

8

Nếu bạn muốn nó tương thích, bạn sẽ phải HIỂN THỊ COLUMN và xác định trước nếu NULL được cho phép. Nếu nó được cho phép thì giá trị rỗng ($ v) sử dụng val = NULL trong truy vấn.

$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

Tôi tạo ra các bảng như là một phần của một phong tục plugin - các cột được đề cập chấp nhận giá trị NULL. – leepowers

+0

@ pygorex1 - Làm thế nào? –

+0

Điều này là khá nhiều giải pháp duy nhất ngoài việc thay đổi ngữ nghĩa NULL/rỗng của plugin của tôi. – leepowers

4

Đây là giải pháp cho vấn đề của bạn. Trong "wp-content" thư mục, tạo một file có tên "db.php" và đặt mã này trong đó:

<?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); 
?> 

Bằng cách này bạn có thể sử dụng các giá trị null với wpdb!

0

Tôi đã cố chỉnh sửa một trong các giải pháp khác được liệt kê ở đây, vì nó dẫn đến mảng định dạng không được căn chỉnh với mảng dữ liệu, nhưng không thành công.

Dưới đây là một giải pháp có thể sửa đổi wpdb từ phiên bản mới nhất của wordpress, để cho phép chèn và cập nhật các giá trị null vào các bảng SQL sử dụng chèn() và cập nhật():

/* 
* 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); 

Chèn mã này vào một nơi nào đó luôn chạy, như functions.php của bạn, và sau đó sử dụng toàn cầu $ wpdb_allowed_null-> insert() và -> update() như bình thường.

Tôi ưa thích phương pháp này so với giá trị mặc định $ wpdb, để duy trì hành vi DB mà phần còn lại của Wordpress và các plugin khác sẽ trông đợi.

1

Tôi tìm thấy điều này trên Wordpress StackExchange diễn đàn và nó hoạt động rất tốt cho tôi.

// 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'); 

và chức năng wp_db_null_value là:

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

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

Bởi vì trong trường hợp của tôi, tôi không thể sử dụng $ db-> chuẩn bị() chức năng ...

+0

Giải pháp tốt nhất! –