Вставка базы данных Wordpress () и обновление () - с использованием значений NULL - PullRequest
7 голосов
/ 08 апреля 2010

Wordpress поставляется с классом wpdb, который обрабатывает операции CRUD. Меня интересуют два метода этого класса: insert() (C в CRUD) и update() (U в CRUD).

Проблема возникает, когда я хочу вставить NULL в столбец базы данных MySQL - класс wpdb экранирует нулевые переменные PHP в пустые строки. Как я могу сказать Wordpress использовать фактический MySQL NULL вместо строки MySQL?

Ответы [ 4 ]

8 голосов
/ 08 апреля 2010

Если вы хотите, чтобы он был совместим, вам нужно ПОКАЗАТЬ КОЛОННУ и заранее определить, разрешен ли 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 ) );
}
4 голосов
/ 27 апреля 2012

Вот решение вашей проблемы. В папке « 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!

1 голос
/ 22 мая 2014

Я нахожу это на 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-> prepare () ...

0 голосов
/ 20 ноября 2013

Я попытался отредактировать одно из других решений, перечисленных здесь, потому что это привело к неправильному выравниванию массива форматов с массивом данных, но не удалось.

Вот решение, которое изменяет wpdb из последней версии WordPress, чтобы позволить вставлять и обновлять нулевые значения в таблицы SQL, используя insert () и 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);

Вставьте этот код в любое место, которое всегда запускается, например, в functions.php, а затем используйте ваши новые глобальные $ wpdb_allowed_null-> insert () и -> update () как обычно.

Я предпочел этот метод вместо переопределения стандартного $ wpdb, чтобы сохранить поведение БД, которое ожидают остальные Wordpress и другие плагины.

...