ГлавнаяРазноеРабота с WP_Error в WordPress

Работа с WP_Error в WordPress

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

Объект класса WP_Error может содержать подробную информацию об ошибке или ошибках, например код возникшей ошибки, сообщение пользователю и дополнительные данные произвольного типа.

Проверка на ошибки

Проверить является ли переменная объектом класса WP_Error можно с помощью внутренней функции PHP is_a(), или с помощью вспомогательной функции ядра WordPress is_wp_error(), например:

$result = wp_remote_get( 'http://google.com' );
if ( is_wp_error( $result ) ) {
    wp_die( 'Ошибка при запросе внешнего ресурса!' );
}

Здесь при запросе внешнего ресурса с помощью функции wp_remote_get() вы можете столкнуться с целым рядом ошибок, например неправильный URL ресурса, недоступность ресурса, слишком много редиректов, ошибка при проверки SSL сертификата и т.д.

Узнать какая именно ошибка возникла вам помогут методы класса WP_Error.

Метод get_error_code()

Метод get_error_code() возвращает код возникшей ошибки. Чаще всего это строка латинских букв или число, которые легко использовать в исходном коде при сравнении. Сам код ошибки редко выводится пользователю на экран.

if ( is_wp_error( $result ) ) {
    $error_code = $result->get_error_code();
    if ( $error_code == 'http_request_failed' ) {
        wp_die( 'Ошибка!' );
    }
}

Объект класса WP_Error может содержать в себе как одну, так и несколько разных ошибок. При таком подходе код ошибки является уникальным ключом для каждой из возникших ошибок, а метод get_error_code() возвращает код первой ошибки в списке.

Получить массив содержащий все коды возникших ошибок можно с помощью метода get_error_codes().

Метод get_error_message()

Метод get_error_message() возвращает сообщение ошибки. Подобные сообщения часто пишут более понятным языком, а также проводят через функции локализации в WordPress, так что сообщения можно смело выводить на экран пользователям:

if ( is_wp_error( $result ) ) {
    wp_die( $result->get_error_message() );
}

Если вы работаете с множественным числом ошибок, то данному методу можно передать код требуемой ошибки, или же воспользоваться методом get_error_messages(), который вернет массив всех сообщений.

Метод get_error_data()

Когда вместе с ошибкой последовали какие-то дополнительные данные, их легко получить с помощью метода get_error_data(), который так же как и get_error_message() может принимать дополнительный аргумент в виде кода ошибки.

if ( is_wp_error( $result ) ) {
    $data = $result->get_error_data( $result->get_error_code() );
}

Собственные ошибки с помощью WP_Error

Помимо обработки ошибок возникающих в ядре WordPress, вы можете создавать собственные объекты класса WP_Error в ваших темах и плагинах. Например:

function my_function() {
    return new WP_Error( 'my_error_code', 'Ошибка при обращении к функции my_function().' );
}

Чтобы добавить несколько ошибок в WP_Error, необходимо сперва создать пустой объект WP_Error, а затем наполнять его с помощью метода add():

function my_function() {
    $error = new WP_Error();
    $error->add( 'my_first_error', 'Первая ошибка' );
    $error->add( 'my_second_error', 'Вторая ошибка' );
    return $error;
}

Вывести все возникшие ошибки на экран можно с помощью простого цикла:

$result = my_function();
if ( is_wp_error( $result ) ) {
    foreach ( $result->get_error_messages() as $message ) {
        echo $message;
    }
}

Пример с формой регистрации

Подход с множественном числом ошибок часто используется при заполнении форм. Ведь лучше вывести все ошибки на экран сразу, нежели заставлять пользователя исправлять их по одной. Для простой формы регистрации это может выглядеть следующим образом:

function my_handle_registration( $username, $email, $password ) {
    $errors = new WP_Error();

    if ( get_user_by( 'login', $username ) )
        $errors->add( 'login_exists', 'Пользователь с таким именем уже существует.' );

    if ( ! is_email( $email ) )
        $errors->add( 'invalid_email', 'Неверный адрес электронной почты.' );

    if ( get_user_by( 'email', $email ) )
        $errors->add( 'email_exists', 'Пользователь с таким e-mail уже существует.' );

    if ( strlen( $password ) < 6  )
        $errors->add( 'weak_password', 'Пароль должен быть не менее 6 символов.' );

    // Если возникла хотя бы одна из ошибок.
    if ( ! empty( $errors->get_error_codes() ) )
        return $errors;

    // Зарегистрировать пользователя
}

Здесь мы сразу проверяем уникальность имени пользователя, правильность и уникальность его адреса электронной почты, а также длину введенного пароля. При возникновении хотя бы одной ошибки, мы возвращаем объект класса WP_Error. Если список ошибок пуст, то мы продолжаем регистрацию пользователя.

На стороне пользовательского интерфейса обработка регистрации может выглядеть следующим образом:

$result = my_handle_registration( $_POST['username'], $_POST['email'], $_POST['password'] );
if ( is_wp_error( $result ) ) {
    echo '<p>При регистрации возникли следующие ошибки:</p>';

    foreach ( $result->get_error_messages() as $message ) {
        printf( '<p>%s</p>', $message );
    }
} else {
    echo '<p>Вы успешно зарегистрировались!</p>';
}

Работа с дополнительными данными

Как мы уже упомянули ранее, каждая ошибка может сопровождаться дополнительными данными. Такой подход редко используется на практике, поскольку кода и сообщения чаще всего хватает. Но с помощью дополнительных данных можно, например, порекомендовать уникальные имена пользователей, если выбранный уже существует:

if ( get_user_by( 'login', $username ) ) {
    $errors->add( 'login_exists', 'Пользователь с таким именем уже существует.' );

    // Рекомендации вида username_1, username_2, ...
    $suggestions = array();
    for ( $i = 1; $i <= 3; $i++ )
        if ( ! get_user_by( 'login', $username . '_' . $i ) )
            $suggestions[] = $username . '_' . $i;

    // Добавить рекомендации к ошибке
    $errors->add_data( $suggestions, 'login_exists' );
}

Прочитать дополнительные данные можно с помощью метода get_error_data().

Заключение

Класс WP_Error и вспомогательная функция is_wp_error() позволяют создавать, передавать и обрабатывать ошибки в WordPress. Это намного удобнее, чем работа со строками, булевыми значениями или глобальными переменными для передачи ошибок, особенно если речь идет о комплексных приложениях на WordPress.

Реализацию класса WP_error можно посмотреть в файле ядра wp-includes/class-wp-error.php.

Константин Ковшенин

Сооснователь журнала WP Magazine и первой конференции WordCamp в России. Работал в Automattic, WordPress.com, WooCommerce. Принимает активное участие в развитии ядра WordPress. Любимый язык программирования: Python.

Подписаться на рассылку

Подписаться → Подпишитесь на бесплатную рассылку журнала WP Magazine и получайте новости, события, подборки тем и плагинов, уроки, советы и многое другое в мире WordPress!