Как получить сообщения об ошибках, когда $wpdb->insert() возвращает false?

23 авг. 2017 г., 15:03:48
Просмотры: 29.3K
Голосов: 17

$wpdb->insert() возвращает false, что, как я узнал, означает, что вставка не удалась. Теперь я хотел бы знать, почему происходит сбой при вставке.

Согласно этому тикету https://core.trac.wordpress.org/ticket/32315 проблема может быть в том, что значение либо слишком длинное, либо содержит недопустимые символы.

Вот запрос на вставку:

$result = $wpdb->insert('table', $ins_args, array('%d', '%d', '%s', '%s', '%s', '%s'));

Сложно показать значения массива $ins_args, так как некоторые значения довольно длинные. Особенно для поля с названием value. Но я использую тип longtext для этого поля. И эта вставка используется часто. И в большинстве случаев она работает успешно. Поэтому действительно похоже на проблему с кодировкой или размером.

Как мне узнать, в чем проблема? $wpdb->last_error пустой

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

Проверьте $wpdb->last_error для ошибки вставки

Anton Lukin Anton Lukin
23 авг. 2017 г. 15:06:35

@Anton Lukin Да, извините, должен был сказать. Конечно пробовал это, но там просто пусто.

Peter Westerlund Peter Westerlund
23 авг. 2017 г. 15:14:34

Попробуйте отладить. Используйте $wpdb->last_query после вставки, затем выполните этот запрос через mysql-клиент, чтобы увидеть ошибку. Это возможно?

Anton Lukin Anton Lukin
23 авг. 2017 г. 15:17:51

@Anton Lukin Хотя последний запрос — это insert(), $wpdb->last_query сразу после показывает запрос типа SELECT * FROM .....

Peter Westerlund Peter Westerlund
23 авг. 2017 г. 15:31:23

Мы можем победить :) добавьте savequeries в ваш wp-config.php https://wordpress.stackexchange.com/a/110270/126253

Anton Lukin Anton Lukin
23 авг. 2017 г. 15:34:17

@Anton Lukin Чёрт, я ошибся с возвращаемым значением. Возвращается false, а не 0. Немного сложно получить запросы в футере, так как мои операции выполняются через ajax. Но я попытался разместить это после кода в php, который вызывает ajax. А затем вызвал его из браузера. Теперь я обнаружил, что что-то ломается по пути, в цикле. Нужно разобраться, в чём дело. Но это что-то происходит уже после неудачного insert. Так что проблема всё ещё есть. Но сложно отладить... Буду продолжать попытки...

Peter Westerlund Peter Westerlund
23 авг. 2017 г. 15:57:42

@Anton Lukin Хорошо, я нашел запрос. Похоже, что здесь ошибка: [75] => Array ( [0] => INSERT INTO results (parent_id, parent_id, key_code, value, url, cat_ids) VALUES (0, 7, 'posts', '', '', '') [1] => 0.0037600994110107 [2] => do_action('wp_ajax_my_save_result'), WP_Hook->do_action, WP_Hook->apply_filters, call_user_func_array, my_save_result, pw_save, PW->save_result, PW->get_posts )

Peter Westerlund Peter Westerlund
23 авг. 2017 г. 16:09:02

Нормально ли, что в вашем запросе дважды указано parent_id, parent_id?

Anton Lukin Anton Lukin
23 авг. 2017 г. 16:12:13

@Anton Lukin Извините, это ошибка, второе поле должно быть parent_x_id. Хотел сделать это немного скрытным.

Peter Westerlund Peter Westerlund
23 авг. 2017 г. 16:15:45

Хорошо, мне удалось исправить это, санируя url и value с помощью esc_url() и esc_html() перед insert();. Всё равно плохо, что нет сообщений об ошибках по этому поводу...

Peter Westerlund Peter Westerlund
23 авг. 2017 г. 16:37:24
Показать остальные 5 комментариев
Все ответы на вопрос 2
3
18

Метод $wpdb->insert() возвращает false, если строка не была вставлена. В противном случае он возвращает количество затронутых строк (которое всегда будет равно 1).

Вы можете включать и выключать отображение ошибок с помощью методов show_errors и hide_errors соответственно.

<?php $wpdb->show_errors(); ?> 
<?php $wpdb->hide_errors(); ?> 

Также можно вывести ошибку (если она есть), сгенерированную последним запросом, с помощью метода print_error.

<?php $wpdb->print_error(); ?> 

Вы также можете использовать поле $last_error, которое будет содержать текст последней ошибки, сгенерированной MySQL.

22 янв. 2019 г. 13:18:56
Комментарии

Было бы полезно увидеть пример поля $last_error. Это просто $wpdb->last_error?

Simon East Simon East
23 янв. 2019 г. 07:07:02

Да, именно $wpdb->last_error

Krzysiek Dróżdż Krzysiek Dróżdż
23 янв. 2019 г. 09:01:07

Обратите внимание, что если запись прерывается из-за слишком длинного столбца, ошибка не возвращается. То есть $wpdb->last_error будет пустым, и ни $wpdb->show_errors(), ни $wpdb->hide_errors() не помогут. В моем ответе ниже приведен способ изменить это поведение.

Brian C Brian C
28 авг. 2020 г. 11:40:47
2

К сожалению, wp-db.php возвращает false без ошибки, если данные, которые вы пытаетесь записать в столбец, слишком длинные и не помещаются. Это превращается в кошмар при отладке без явной проверки длины каждого столбца (хотя узнать длины сложно, хотя wp-db.php предоставляет внутренние функции).

Я создал небольшой переопределяющий файл, который изменяет поведение wpdb, чтобы возвращать ошибку в этом сценарии. Чтобы установить его, вам просто нужно скопировать и вставить его в файл WordPress wp-content/db.php. Он переопределяет только один короткий метод wpdb (process_fields()), чтобы добавить сообщение об ошибке, идентифицирующее слишком длинный столбец. Обратите внимание, что db.php сохранится при обновлениях ядра, и вы можете просто удалить файл wp-content/db.php в любое время, чтобы вернуться к чистому wpdb из ядра.

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

Код ошибки изначально взят из идеи Лиама Мерфи здесь.

Gist для файла db.php здесь

28 авг. 2020 г. 11:37:14
Комментарии

Наконец исправлено в WordPress v5.9. https://core.trac.wordpress.org/ticket/32315#comment:82

Bence Szalai Bence Szalai
9 февр. 2022 г. 19:07:52

Наконец-то!! Спасибо.

Brian C Brian C
10 февр. 2022 г. 04:54:08