Класс WP_Error призван упростить работу с ошибками, которые вызваны либо некорректным действием пользователем, либо каких-то сторонних приложений или плагинов.
То есть таким образом мы даже можем разделить ошибки на два типа:
- ошибки разработчика, который(ая) скажем пишет плагин или тему – в таком случае, если там вызывается например несуществующая функция или наоборот функция определяется дважды, то всё легко и понятно – мы получаем либо белый экран, либо ошибку 500 в лицо,
- ошибки пользователя, ошибки API и прочее, например если пользователь в поле ввода email указал 123, либо попытался зарегистрироваться под email, который уже существует на сайте или например API инстаграм послал нас, то такие ошибки нам удобно обрабатываться классом WP_Error, который WordPress нам предоставляет.
Как и в любом другом классе, у нас имеется набор методов и свойств, о которых мы поговорим обязательно, но сначала давайте научимся работать с классом WP_Error.
Также хотел бы порекомендовать вам свой видеокурс по разработке темы WordPress с нуля.
Использование класса WP_Error
Обработка ошибок
В целом можно поговорить о тех же самых примерах, которые я упоминал чуть выше (пользователь указал уже существующий email, api инсты нас послал).
В первом случае попробуем воспользоваться функциями:
- wp_insert_user() – для создания пользователя (она и будет возвращать нам ошибку
WP_Error
). - is_wp_error() – для проверки на ошибку.
- wp_die() – для прекращения выполнения кода и вывода сообщения об ошибке.
$user = wp_insert_user( ... ); if( is_wp_error( $user ) ) { wp_die( 'С регистрацией пользователя что-то пошло не так.' ); }
Сделаем код немного интереснее, а точнее – проверим, что функция wp_insert_user() именно возвращает нам ошибку на уже существующий email, а не какую-либо другую, для этого мы воспользуемся методом get_error_code()
. Что касается кода ошибки, existing_user_email
, то его я прочекал непосредственно внутри функции.
$user = wp_insert_user( ... ); if( is_wp_error( $user ) ) { if( 'existing_user_email' === $user->get_error_code() ) { wp_die( 'Данный email уже зарегистрирован на сайте' ); } }
Но мы также можем использовать стандартное сообщения об ошибке! Ещё раз слегка меняем наш код, добавив метод get_error_message()
.
$user = wp_insert_user( ... ); if( is_wp_error( $user ) ) { if( 'existing_user_email' === $user->get_error_code() ) { wp_die( $user->get_error_message() ); } }
Итак, второй случай – обращение к внешнему API, как мы договорились раньше, это может быть инстаграм например.
Предположим, что подключения к API мы воспользуемся либо wp_remote_get()
, либо wp_remote_post()
.
$response = wp_remote_post( 'https://инстаграмапи', array( 'timeout' => 30, 'body' => ... ) ); if ( is_wp_error( $response ) ) { echo 'Ошибка: ' . $response->get_error_message(); } else { // тут всё ок, выводим фото например }
Создание объекта WP_Error
Тут по сути есть два варианта – либо мы добавляем одну ошибку, и это можно сделать сразу же при создании объекта WP_Error
, либо мы добавляем несколько ошибок, используя метод add().
Для того, чтобы не придумывать ничего сложного, мы можем создать функцию, которая сразу же будет возвращать объект ошибки.
function true_wp_error_function() { return new WP_Error( 'true_error', 'Это ошибка, ребят' ); }
Затем мы можем вызвать эту функцию и вывести сообщение об ошибке из неё.
$maybe_error = true_wp_error_function(); if( is_wp_error( $maybe_error ) ) { echo $maybe_error->get_error_message(); // Это ошибка, ребят }
Также хочу обратить ваше внимание на то, что вам никто не мешает распечатать получившийся объект функцией print_r( $maybe_error )
. Тогда результат будет следующим:
WP_Error Object ( [errors] => Array ( [true_error] => Array ( [0] => Это ошибка, ребят ) ) [error_data] => Array ( [true_error] => Это ошибка, ребят ) )
Теперь попробуем сделать то же самое, но обработаем несколько ошибок.
function true_wp_error_function() { $errors = new WP_Error(); $errors->add( 'true_error_1', 'Это ошибка, ребят' ); $errors->add( 'true_error_2', 'Это вторая ошибка' ); return $errors; }
Для того, чтобы вывести несколько сообщений об ошибке, то метода get_error_message() уже будет недостаточно. Воспользуемся get_error_messages().
$most_likely_errors = true_wp_error_function(); if( is_wp_error( $most_likely_errors ) ) { foreach ( $most_likely_errors->get_error_messages() as $message ) { echo '<p class="err">' . $message . '</p>'; } }
И конечно, если распечатать всё это при помощи print_r( $most_likely_errors )
, то получим:
WP_Error Object ( [errors] => Array ( [true_error_1] => Array ( [0] => Это ошибка, ребят ) [true_error_2] => Array ( [0] => Это вторая ошибка ) ) [error_data] => Array ( [true_error_1] => Это ошибка, ребят [true_error_2] => Это вторая ошибка ) )
Работаем с дополнительными данными ошибок
Чаще всего, при работе с ошибками WP_Error
, кода и сообщения об ошибки хватает вполне. Но вполне возможно, что может существовать такая ситуация, когда вы захотите сопроводить вашу ошибку какими-либо дополнительными данными, и класс WP_Error
позволяет нам сделать это!
В качестве примера можем рассмотреть ситуацию, когда пользователь пытается зарегистрироваться под именем пользователя, которое уже существует на сайте! Давайте автоматически сгенерируем и предложим ему другие варианты имён!
А для проверки того, что пользователь с указанным именем пользователя существует (или нет), мы воспользуемся функцией get_user_by().
if ( get_user_by( 'login', $username ) ) { $errors = new WP_Error(); $errors->add( 'login_exists', 'Пользователь с таким именем уже существует.' ); // Давайте порекомендуем имена с цифрами на конце $suggestions = array(); for ( $i = 1; $i <= 3; $i++ ) { if ( ! get_user_by( 'login', $username . '_' . $i ) ) { $suggestions[] = $username . '_' . $i; } } // И с годом рождения пользователя, если он указан if( $birthday_year && ! get_user_by( 'login', $username . '_' . $birthday_year ) ) { $suggestions[] = $username . '_' . $birthday_year; } // Добавляем рекомендации к ошибке $errors->add_data( $suggestions, 'login_exists' ); }
Для того, что получить эти рекомендации из ошибки, мы можем воспользоваться методом get_data(). А если распечатаем объект в print_r( $errors )
, то получим:
WP_Error Object ( [errors] => Array ( [login_exists] => Array ( [0] => Пользователь с таким именем уже существует. ) ) [error_data] => Array ( [login_exists] => Array ( [0] => misha_1 [1] => misha_2 [2] => misha_3 [3] => misha_1995 ) ) )
Свойства класса WP_Error
У WP_Error
есть три приватных свойства – $errors
, $error_data
и $additional_data
, некоторые из которых вы кстати уже могли заметить чуть выше, когда мы распечатывали целый объект WP_Error
. Как бы там ни было, к этим свойствам мы никогда не пытаемся обратиться напрямую и используем для этого соответствующие методы. В свойстве $errors
хранится список ошибок и их сообщений, а $error_data
, помимо сообщений, хранит ещё какие-либо дополнительные данные для каждого кода ошибки, о которых мы поговорим чуть позже тоже.
Методы класса WP_Error
__construct()
Этот метод-конструктор срабатывает автоматически, когда мы создаём объект класса WP_Error
, то есть new WP_Error()
.
__construct( $code = '', $message = '', $data = '' )
- $code
- (строка) Код ошибки, в котором мы по умолчанию используем латинские буквы в нижнем регистре, символы подчёркивания и цифры, но начинаем его не с цифры.
- $message
- (строка) Сообщение об ошибке.
- $data
- (смешанный) Любые дополнительные данные, ассоциированные с этой ошибкой.
Например мы уже использовали этот метод в примерах выше, когда создавали объект класса, вот так:
$error_object = new WP_Error( 'true_error', 'Это ошибка, ребят' );
get_error_code()
Позволяет получить код ошибки. Если в объекте WP_Error
записано несклько ошибок, то получает код первой из них.
echo $error_object->get_error_code(); // если используем объект из предыдущего примера, то получим "true_error"
get_error_codes()
В примерах выше мы с вами уже убедились, что в объекте WP_Error может быть записано несколько ошибок, в таком случае для их получения нам не подойдёт метод get_error_code(), но к счастью у нас ещё и метод get_error_codes()
, который вернёт все существующие ошибки в объекте в виде массива.
foreach( $error_object->get_error_codes() as $error_code ) { echo $error_code; }
print_r( $error_object->get_error_codes() ); /* возвращает примерно так Array ( [0] => true_error [1] => true_error_2 ) */
get_error_message()
Данный метод позволяет вернуть сообщение об ошибке, соотвтствующее определённому коду ошибки. Но если параметр с кодом ошибки не передан в метод, то возвращает первое сообщение об ошибки из объекта.
get_error_message( $code = '' )
- $code
- (строка|целое число) Тут можно указать код ошибки, но это не обязательно.
К примеру у нас есть вот такой объект WP_Error
, который мы кстати создавали чуть выше
WP_Error Object ( [errors] => Array ( [true_error_1] => Array ( [0] => Это ошибка, ребят ) [true_error_2] => Array ( [0] => Это вторая ошибка ) ) [error_data] => Array ( [true_error_1] => Это ошибка, ребят [true_error_2] => Это вторая ошибка ) )
При помощи get_error_message()
мы можем вывести как сообщение об ошибке с определённым кодом, так и самое первое из сообщений. Чекайте:
echo $error->get_error_message(); // Это ошибка, ребят
echo $error->get_error_message( 'true_error_2' ); // Это вторая ошибка
get_error_messages()
Данный метод позволяет вернуть сообщение об ошибке, соотвтствующее определённому коду ошибки. Но если параметр с кодом ошибки не передан в метод, то возвращает массив, состоящий из всех сообщений об ошибке.
На примере объекта из предыдущего примера.
print_r( $error->get_error_messages() ); /* Array ( [0] => Это ошибка, ребят [1] => Это вторая ошибка ) */
Конечно, мы можем это вывести и при помощи цикла foreach()
.
foreach ( $error->get_error_messages() as $message ) { printf( '<p>%s</p>', $message ); }
Ну или выводим определённую ошибку:
echo $error->get_error_messages( 'true_error_2' ); // Это вторая ошибка
get_error_data()
Позволяет получить дополнительные данные, добавленные в ошибку.
get_error_data( $code = '' )
- $code
- (целое число|строка) Код ошибки, дополнительные данные которой нужно получить. Параметр не обязатален, и если его не указать, то метод будет возвращать дополнительные данные самой первой ошибки в объекте.
Давайте попробуем получить дополнительные данные ошибки из этого примера.
$suggestions = $errors->get_error_data( 'login_exists' ); if( $suggestions && is_array( $suggestions ) ) { echo 'Попробуйте эти имена пользователей:'; foreach ( $suggestions as $suggested_username ) { printf( '<p>%s</p>', $suggested_username ); } }
has_errors()
Возвращает true
или false
в зависимости от того, есть ли ошибки внутри заданного объекта WP_Error
. Метод появился в версии WordPress 5.1.
if( $error->has_errors() ) { // выводим ошибки foreach ( $error->get_error_messages() as $message ) { printf( '<p>%s</p>', $message ); } } else { echo '<p>Что-то пошло не так, но мы не знаем, что.</p>'; }
add()
Позволяет добавить ошибку в объект WP_Error
.
add( $code, $message, $data = '' )
- $code
- (строка) Код ошибки, в котором мы по умолчанию используем латинские буквы в нижнем регистре, символы подчёркивания и цифры, но начинаем его не с цифры.
- $message
- (строка) Сообщение об ошибке.
- $data
- (смешанный) Любые дополнительные данные, ассоциированные с этой ошибкой.
add_data()
Позволяет добавить дополнительные данные для ошибки с определённым кодом. Если код ошибки не задан, то данные добавятся в самую первую ошибку в объекте. Этот метод мы уже использовали в примере.
add_data( $data, $code = '' )
- $data
- (смешанный) Любые дополнительные данные, ассоциированные с ошибкой.
- $code
- (строка) Код ошибки.
remove()
Этот метод удаляет из объекта WP_Error
ошибку с определённым кодом.
remove( $code )
-
$code
- (строка) Указываем тут код ошибки, которую хотим удалить, параметр обязателен кстати.
Источник: Блог Миши Рудрастых