Класс WP_Error

Класс 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
(строка) Указываем тут код ошибки, которую хотим удалить, параметр обязателен кстати.

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

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

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал