2010-04-08 2 views
7

Wordpress est livré avec la classe wpdb qui gère les opérations CRUD. Les deux méthodes de cette classe qui m'intéressent sont le insert() (le C dans CRUD) et le update() (le U dans CRUD).Base de données Wordpress insert() et update() - utilisant les valeurs NULL

Un problème survient lorsque je veux insérer une valeur NULL dans une colonne de base de données mysql - la classe wpdb échappe à des variables nulles PHP pour vider des chaînes. Comment puis-je dire à Wordpress d'utiliser un véritable MySQL NULL au lieu d'une chaîne MySQL?

Répondre

8

Si vous le voulez compatible, vous devez afficher COLUMN et déterminer à l'avance si NULL est autorisé. Si cela était autorisé, si la valeur était vide ($ v), utilisez val = NULL dans la requête.

$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

J'ai créé les tables dans le cadre d'une coutume plugin - les colonnes en question acceptent les valeurs NULL. – leepowers

+0

@ pygorex1 - Comment ça? –

+0

C'est à peu près la seule solution en plus de changer la sémantique NULL/vide de mon plugin. – leepowers

4

Voici une solution à votre problème. Dans "wp-content" dossier, créez un fichier nommé "db.php" et mettre ce code en elle:

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

De cette façon, vous pouvez utiliser des valeurs nulles avec wpdb!

0

J'ai essayé d'éditer l'une des autres solutions répertoriées ici, car cela a entraîné l'alignement incorrect du tableau de format avec le tableau de données, mais a échoué.

Voici une solution qui modifie la wpdb de la dernière version de wordpress, afin de permettre l'insertion et la mise à jour des valeurs NULL dans des tables SQL à l'aide d'insertion() et mise à jour():

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

Insérer ce code dans un endroit qui est toujours exécuté, comme vos fonctions.php, puis utilisez votre nouveau global $ wpdb_allowed_null-> insert() et -> update() comme d'habitude.

J'ai préféré cette méthode par rapport à la valeur par défaut $ wpdb, afin de préserver le comportement de la DB que le reste de Wordpress et d'autres plugins attendra.

1

Je le trouve sur le forum Wordpress StackExchange et ça marche très bien pour moi.

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

et la fonction wp_db_null_value est:

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

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

Parce que dans mon cas, je ne peux pas utiliser $ db-> prepare() fonction ...

+0

Meilleure solution yeat! –

Questions connexes