Почему $wpdb->last_error не показывает запрос при ошибке

29 апр. 2016 г., 13:22:34
Просмотры: 16.1K
Голосов: 5

Я вставляю данные в пользовательскую таблицу с помощью $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, и вставка прошла успешно без ошибок.

1
Комментарии

Та же проблема, ваше решение сработало. Спасибо!

Allen Gingrich Allen Gingrich
23 июл. 2019 г. 20:23:07
Все ответы на вопрос 3
3

Если вам нужен сам запрос, используйте $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).

29 апр. 2016 г. 13:35:17
Комментарии

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

Ghazanfar Mir Ghazanfar Mir
29 апр. 2016 г. 13:45:11

Обновил ответ с возможным объяснением.

TheDeadMedic TheDeadMedic
29 апр. 2016 г. 13:52:02

Так какой же лучший способ сделать это работоспособным? То есть всегда получать сообщение в last_error при ошибках

Ghazanfar Mir Ghazanfar Mir
29 апр. 2016 г. 14:08:39
3

https://core.trac.wordpress.org/ticket/32315

Один из входных параметров столбца может быть больше, чем сам столбец. WordPress обнаруживает это и даже не отправляет запрос в базу данных.

Разница (Diff) там показывает патч для wp-db, который вы можете применить, чтобы получить больше информации в сообщении last_error, чтобы оно не было пустым.

Ошибка WordPress: превышение размера столбца

10 мар. 2019 г. 08:27:51
Комментарии

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

Brian C Brian C
28 авг. 2020 г. 11:57:13

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

Liam Mitchell Liam Mitchell
29 авг. 2020 г. 04:24:37

Похоже, исправление в ядре предложено, но не попало в 5.5 и, думаю, в 5.6. Будем надеяться, вздох.

Brian C Brian C
29 авг. 2020 г. 04:25:58
1

Попробуйте это

// Включение отображения ошибок базы данных
$wpdb->show_errors();
// Вставка данных в таблицу
$result = $wpdb->insert($this->table, $data_);
29 апр. 2016 г. 13:42:43
Комментарии

Извините, к сожалению, это не работает. Проблема в том, что ошибка вызвана кодом wpdb, который просто завершается с false и не устанавливает last_error.

Brian C Brian C
28 авг. 2020 г. 11:44:50