Почему $wpdb->last_error не показывает запрос при ошибке
Я вставляю данные в пользовательскую таблицу с помощью $wpdb->insert
. Однако при ошибке я не получаю никакой информации из $wpdb->last_error
. В чем может быть причина?
У меня уже есть такая конфигурация в wp-config.php
:
define('WP_DEBUG', false);
define('SAVEQUERIES', true);
Код выглядит следующим образом:
$result = $wpdb->insert($this->table, $data_);
if (false === $result) {
error_log($wpdb->last_error);
}
$this->table
и $data_
заполнены корректно, так как запрос выполняется успешно. Но я не получаю информации о запросе, который завершился ошибкой. Есть ли способ получить фактический запрос, выполняемый в $wpdb->insert
?
Решение
Итак, я разобрался с проблемой. Запрос на вставку завершался ошибкой, потому что данные для одного из столбцов были слишком большими и превышали размер столбца в базе данных. Столбец был varchar(500)
, но фактические данные превышали 500 символов, что приводило к ошибке. Я изменил тип столбца на TEXT
, и вставка прошла успешно без ошибок.
Если вам нужен сам запрос, используйте $wpdb->last_query
(обратите внимание, что вам не нужно включать SAVEQUERIES
, это нужно только если вам нужна запись всех запросов ($wpdb->queries
)).
last_error
— это... ну, ошибка!
Обновление: Возможное объяснение, почему last_error
пуст — вот исходный код wpdb::query()
:
// Если мы записываем в базу данных, убедимся, что запрос будет выполнен безопасно.
if ( $this->check_current_query && ! $this->check_ascii( $query ) ) {
$stripped_query = $this->strip_invalid_text_from_query( $query );
// strip_invalid_text_from_query() может выполнять запросы, поэтому
// нужно снова сбросить, чтобы убедиться, что все чисто.
$this->flush();
if ( $stripped_query !== $query ) {
$this->insert_id = 0;
return false;
}
}
// Удаленный код
// Сохраняем последний запрос для отладки...
$this->last_query = $query;
$this->_do_query( $query );
// Удаленный код
// Если есть ошибка, записываем её...
if ( $this->use_mysqli ) {
$this->last_error = mysqli_error( $this->dbh );
} else {
$this->last_error = mysql_error( $this->dbh );
}
Другими словами, WordPress заранее проверяет запрос и прерывает выполнение, если считает, что он завершится неудачей — в этом случае вы получите return false
, но ошибка не будет установлена (поскольку запрос вообще не был отправлен на сервер MySQL).

но почему я всё ещё не получаю ничего в last_error? insert запрос возвращает false, что означает, что что-то пошло не так, но при этом last_error остаётся пустым? Странно?

https://core.trac.wordpress.org/ticket/32315
Один из входных параметров столбца может быть больше, чем сам столбец. WordPress обнаруживает это и даже не отправляет запрос в базу данных.
Разница (Diff) там показывает патч для wp-db, который вы можете применить, чтобы получить больше информации в сообщении last_error, чтобы оно не было пустым.

Это действительно крутой ответ. Я адаптировал ваш ответ в файл wp-content/db.php, чтобы его можно было легко и быстро установить на место для постоянного решения, которое сохранится после обновлений WordPress. Смотрите здесь gist и подробности.

О, отлично, спасибо @BrianC, я недавно видел письмо, что у этой проблемы теперь есть этап в версии 5.6.
