2010-04-08 26 views
7

Wordpress se envía con la clase wpdb que maneja las operaciones CRUD. Los dos métodos de esta clase que me interesan son insert() (la C en CRUD) y update() (la U en CRUD).Insertar base de datos de Wordpress() y actualizar() - utilizando valores NULL

Surge un problema cuando quiero insertar un NULL en una columna de la base de datos mysql - la clase wpdb escapa de las variables nulas de PHP a las cadenas vacías. ¿Cómo puedo decirle a Wordpress que use un MySQL real NULL en lugar de una cadena MySQL?

Respuesta

8

Si desea que sea compatible, deberá MOSTRAR COLUMNA y determinar si está permitido NULL. Si fue permitido, entonces si el valor estaba vacío ($ v) use val = NULL en la consulta.

$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

que creó las tablas como parte de una costumbre complemento: las columnas en cuestión aceptan valores NULOS. – leepowers

+0

@ pygorex1 - ¿Cómo es esto? –

+0

Esta es prácticamente la única solución aparte de cambiar la semántica NULL/empty de mi complemento. – leepowers

4

Aquí hay una solución a su problema. En "wp-content" carpeta, cree un archivo llamado "db.php" y poner este código en él:

<?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 esta manera se puede utilizar valores nulos con wpdb!

0

Traté de editar una de las otras soluciones enumeradas aquí, porque resultó en que la matriz de formato estaba desalineada con la matriz de datos, pero falló.

Aquí es una solución que se modifica la wpdb de la última versión de WordPress, con el fin de permitir la inserción y actualización de los valores nulos en las tablas de SQL mediante inserción() y 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); 

Inserta este código en algún lugar que siempre se ejecute, como su functions.php, y luego use su nueva $ wpdb_allowed_null-> insert() y -> update() global como es normal.

Preferí este método versus el predeterminado $ wpdb, para preservar el comportamiento de la base de datos que el resto de Wordpress y otros complementos esperarán.

1

Encuentro esto en el foro Wordpress StackExchange y funciona muy bien para mí.

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

y la wp_db_null_value función es:

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

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

Debido a que en mi caso no puedo usar $ db-> preparar la función() ...

+0

¡La mejor solución! –

Cuestiones relacionadas