2010-04-08 10 views
7

Wordpress viene fornito con la classe wpdb che gestisce le operazioni CRUD. I due metodi di questa classe a cui sono interessato sono lo insert() (il C in CRUD) e lo update() (l'U in CRUD).Wordpress database insert() e update() - utilizzando valori NULL

Un problema sorge quando voglio inserire un NULL in una colonna di database mysql - la classe wpdb sfugge le variabili nulle PHP alle stringhe vuote. Come posso dire a Wordpress di usare un vero MySQL NULL invece di una stringa MySQL?

risposta

8

Se si desidera che sia compatibile, è necessario MOSTRARE COLONNA e determinare in anticipo se è consentito NULL. Se era permesso, allora se il valore era vuoto ($ v) usa val = NULL nella query.

$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

ho creato le tabelle così come parte di un costume plug-in: le colonne in questione accettano valori NULL. – leepowers

+0

@ pygorex1 - Come è? –

+0

Questa è praticamente l'unica soluzione a parte cambiare la semantica NULL/vuota del mio plugin. – leepowers

4

Ecco una soluzione al tuo problema. In "wp-content" della cartella, creare un file denominato "db.php" e inserire questo codice in esso:

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

In questo modo è possibile utilizzare valori nulli con wpdb!

0

Ho provato a modificare una delle altre soluzioni elencate qui, perché ha provocato il disallineamento dell'array di formato con l'array di dati, ma non è riuscito.

Ecco una soluzione che modifica il wpdb dall'ultima versione di wordpress, al fine di consentire l'inserimento e l'aggiornamento dei valori nulli in tabelle SQL tramite inserto() e update():

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

Inserisci questo codice in qualche luogo che viene sempre eseguito, come il tuo functions.php, e poi usa il tuo nuovo global $ wpdb_allowed_null-> insert() e -> update() come al solito.

Ho preferito questo metodo rispetto a quello predefinito $ wpdb, al fine di preservare il comportamento del DB che si aspetta il resto di Wordpress e altri plug-in.

1

Lo trovo sul forum Wordpress StackExchange e funziona molto bene per me.

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

e la funzione 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); 
} 

Perché nel mio caso non posso usare $ db-> preparare function() ...

+0

La migliore soluzione yeat! –

Problemi correlati