$wpdb не вставляет NULL в столбец таблицы
Когда я пытаюсь сделать так:
$wpdb->update(
'table',
['status' => NULL],
['id' => 1]
);
В столбце status оказывается пустая строка '', а не NULL, как ожидалось.
Столбец определен как NULL в структуре таблицы. Я также пробовал методы $wpdb->query и $wpdb->prepare, но результат тот же. Что я делаю не так?
Обновление:
Начиная с WordPress 4.4, это теперь поддерживается методами insert, update, replace и delete класса wpdb, а тикет #15158 был закрыт с пометкой исправлено.
Спасибо @dmsnell за комментарий об этом обновлении.
С другой стороны, поддержка null в wpdb::prepare() в настоящее время закрыта с пометкой не будет исправлено в тикете #12819.
Предыдущий ответ:
NULL не поддерживается:
Похоже, вам придется написать собственный SQL-запрос для обновления значения на NULL.
В настоящее время NULL не поддерживается в $wpdb->prepare(), который обрабатывает входные данные через функцию форматирования vsprintf.
Ознакомьтесь с этими открытыми тикетами в Trac:
Этим тикетам уже около 4 лет, так что вряд ли стоит ожидать скорой реализации этой функции в ядре ;-)
Как предложил @s_ha_dum, вам следует изучить исходный код.
Возможное решение:
Если вы готовы к экспериментам, можете попробовать следующий подход с фильтром query:
// Добавляем фильтр для замены строки 'NULL' на NULL
add_filter( 'query', 'wpse_143405_query' );
global $wpdb;
$wpdb->update(
'table',
array(
'status' => 'NULL',
),
array( 'id' => 1 )
);
// Удаляем фильтр:
remove_filter( 'query', 'wpse_143405_query' );
где
/**
* Заменяет строку 'NULL' на NULL
*
* @param string $query
* @return string $query
*/
function wpse_143405_query( $query )
{
return str_ireplace( "'NULL'", "NULL", $query );
}
Возможно, стоит использовать более уникальную строку вместо 'NULL', например '###NULL###'.
поддержка установки NULL была добавлена в r34737, поэтому больше нет необходимости в обходных решениях
dmsnell
wpdb->update по умолчанию обрабатывает все типы данных как строки.
format
(array|string) (необязательный) Массив форматов, которые будут применены к каждому значению в $data. Если передана строка, этот формат будет использоваться для всех значений в $data. Если параметр опущен, все значения в $data будут обрабатываться как строки, если не указано иное вwpdb::$field_types.
Вы можете указать формат, но допустимыми спецификаторами являются:
Возможные значения формата: %s для строки; %d для целого числа и %f для числа с плавающей запятой. (Подробности см. ниже.) Если параметр опущен, все значения в $where будут обрабатываться как строки.
Вы можете изучить исходный код и разобраться в процессе.
Если вы измените метод wpdb->prepare (на тестовом сервере, который периодически очищается :)), чтобы вывести SQL прямо перед возвратом, вы увидите, что замена происходит до вызова wpdb->prepare:
string(48) "UPDATE `table` SET `status` = %s WHERE `id` = %s"
Хотя, как отметил @birgire, это может быть ограничением метода prepare, которое привело к такой замене.
Я хочу подробнее объяснить, как это сделать в WordPress 4.4 и более поздних версиях. Вам нужно установить для элемента данных и формата, который вы хотите сделать нулевым, значение PHP 'null'.
Пример из тикета #15158 выглядит следующим образом:
$wpdb->update($ttable,
[
'user_id' => NULL,
'status' => 'available',
'update_time' => $now->format('Y-m-d H:i:s')
], [
'therapist_id' => $therapist_id,
'user_id' => $user_id,
'start_time' => $ub['start_time']
], [
NULL,
'%s',
'%s'
], [
'%d',
'%d',
'%s'
]);