Существует ли что-то вроде is_rest()

20 мар. 2016 г., 14:48:48
Просмотры: 18.9K
Голосов: 34

Я начинаю работать с REST API. Если я не ошибаюсь, хук действия init также выполняется при REST API запросе. Теперь мне нужно выполнять некоторый код только тогда, когда это не REST API запрос.

Я искал что-то вроде функции is_rest(), чтобы сделать следующее:

<?php
if( ! is_rest() ) echo 'no-rest-request';
?>

Но я не смог найти ничего подобного. Существует ли is_rest() в WordPress?

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

Может быть, вы можете подробнее рассказать, что вы хотите делать, когда это не REST-запрос? Тип запроса определяется только во время парсинга запроса, который происходит после init. Также обратите внимание, что части API могут использоваться внутренне для запросов, которые не являются REST-запросами, поэтому вы рискуете что-то сломать, если полагаетесь на эту проверку.

Milo Milo
20 мар. 2016 г. 18:39:42

Большое спасибо вам обоим. @birgire: Не могли бы вы опубликовать это как ответ, чтобы я мог его отметить. По сути, это и есть ответ на мой вопрос :)

websupporter websupporter
21 мар. 2016 г. 08:58:49
Все ответы на вопрос 8
1
22

Это верное замечание от @Milo, константа REST_REQUEST определяется как true внутри функции rest_api_loaded(), если $GLOBALS['wp']->query_vars['rest_route'] не пуста.

Она подключается к parse_request через:

add_action( 'parse_request', 'rest_api_loaded' );

но parse_request срабатывает позже, чем init - Смотрите, например, Кодекс здесь.

Было предложение (от Daniel Bachhuber) в тикете #34373 относительно WP_Query::is_rest(), но оно было отложено/отменено.

21 мар. 2016 г. 16:34:39
Комментарии

#42061 может добавить wp_is_rest_request() или wp_doing_rest().

Ian Dunn Ian Dunn
10 мар. 2020 г. 21:40:35
3
22

Только что столкнулся с той же проблемой и написал простую функцию is_rest, которая позволяет проверить, является ли текущий запрос запросом к WP REST API.

<?php

if ( !function_exists( 'is_rest' ) ) {
    /**
     * Проверяет, является ли текущий запрос запросом к WP REST API.
     *
     * Случай #1: После инициализации WP_REST_Request
     * Случай #2: Поддержка "простых" настроек постоянных ссылок и проверка, начинается ли `rest_route` с `/`
     * Случай #3: Может случиться, что WP_Rewrite еще не инициализирован,
     *            поэтому делаем это (wp-settings.php)
     * Случай #4: Путь URL начинается с wp-json/ (ваш REST префикс)
     *            Также поддерживает установки WP в подпапках
     *
     * @returns boolean
     * @author matzeeable
     */
    function is_rest() {
        if (defined('REST_REQUEST') && REST_REQUEST // (#1)
                || isset($_GET['rest_route']) // (#2)
                        && strpos( $_GET['rest_route'], '/', 0 ) === 0)
                return true;

        // (#3)
        global $wp_rewrite;
        if ($wp_rewrite === null) $wp_rewrite = new WP_Rewrite();
            
        // (#4)
        $rest_url = wp_parse_url( trailingslashit( rest_url( ) ) );
        $current_url = wp_parse_url( add_query_arg( array( ) ) );
        return strpos( $current_url['path'] ?? '/', $rest_url['path'], 0 ) === 0;
    }
}

Ссылки:

18 окт. 2018 г. 20:02:11
Комментарии

Я не понял, что делает пункт #3.

kodfire kodfire
20 июн. 2022 г. 11:43:54

Это лучшая функция для WordPress, когда-либо написанная на Stackoverflow. Мне нужно было использовать её для хука pre_get_posts, который игнорирует REST-запросы, и она сработала идеально.

Philip Philip
25 янв. 2023 г. 10:12:46

Ах! Теперь я понимаю, в чём проблема с популярным плагином, который скопировал ваш код 2018 года, но не учёл (очень важное) изменение, которое вы внесли в 2022! Отличная работа :-) Спасибо за обновление!

Gwyneth Llewelyn Gwyneth Llewelyn
24 сент. 2023 г. 14:28:36
0
13

Если вам нужно проверить после срабатывания init:

defined('REST_REQUEST') && REST_REQUEST

Если нужно проверить до init, есть два способа:

Используйте wp_is_json_request() (добавлено в WordPress 5.0) или попробуйте определить REST-запрос по URL. Определение URL будет отличаться в зависимости от того, используются ли ЧПУ или обычные ссылки.

WooCommerce делает это следующим образом, и это хорошее решение:

function is_rest_api_request() {
    if ( empty( $_SERVER['REQUEST_URI'] ) ) {
        // Вероятно, это CLI-запрос
        return false;
    }

    $rest_prefix         = trailingslashit( rest_get_url_prefix() );
    $is_rest_api_request = strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) !== false;

    return apply_filters( 'is_rest_api_request', $is_rest_api_request );
}
22 янв. 2020 г. 15:46:34
1

Здесь есть два варианта:

  1. Проверить, определена ли константа REST_REQUEST.
  2. Использовать хук rest_api_init вместо того, чтобы вешать обработчик на хук init.
10 мар. 2019 г. 22:28:26
Комментарии

Если вы используете версию WP 4.4.0 или новее (а скорее всего так и есть), это правильный ответ.

Mat Lipe Mat Lipe
5 окт. 2020 г. 22:54:38
0

Для решения этой проблемы я написал простую пользовательскую функцию, основанную на предположении, что если запрашиваемый URI относится к URL Rest API сайта WordPress, то это означает, что это запрос к Rest API.

Является ли конечная точка валидной или аутентифицированной, эта функция не определяет. Вопрос в следующем: является ли URL потенциальным URL Rest API?

function isRestUrl() {
    $bIsRest = false;
    if ( function_exists( 'rest_url' ) && !empty( $_SERVER[ 'REQUEST_URI' ] ) ) {
        $sRestUrlBase = get_rest_url( get_current_blog_id(), '/' );
        $sRestPath = trim( parse_url( $sRestUrlBase, PHP_URL_PATH ), '/' );
        $sRequestPath = trim( $_SERVER[ 'REQUEST_URI' ], '/' );
        $bIsRest = ( strpos( $sRequestPath, $sRestPath ) === 0 );
    }
    return $bIsRest;
}

Если ваш $_SERVER['REQUEST_URI'] не заполнен корректно, эта функция всё равно вернёт false.

Жёсткого кодирования URL нет, поэтому если вы по какой-то причине измените базовый URL API, функция адаптируется.

8 сент. 2017 г. 11:29:35
3

Возможно, не совсем правильно, но в итоге получилось так:

if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
    // Здесь крутые API-штуки
}

Буду рад, если укажете, если это неверно. Пытаюсь сделать полезный стартер для плагина, чтобы впоследствии поделиться: https://gitlab.com/ripp.io/wordpress/plugin-starter

30 мая 2019 г. 18:36:41
Комментарии

Думаю, это не сработает, если у вас не включены красивые постоянные ссылки.

websupporter websupporter
10 июн. 2019 г. 12:34:07

Вы абсолютно правы

Charly Charly
11 июн. 2019 г. 17:25:40

Да, это требует красивых постоянных ссылок... но кто же их не хочет использовать?! Мне кажется, это самый надежный способ. Все остальные решения выглядят изящно, но если вы хотите, чтобы ваш код работал в будущих версиях WP... этот способ кажется мне самым безопасным!!

Antony Gibbs Antony Gibbs
30 июл. 2019 г. 09:21:39
1

В WordPress 6.5 ядро предоставляет функцию wp_is_rest_endpoint для надежного определения, является ли текущий запрос запросом к конечной точке REST.

Также есть другая функция wp_is_serving_rest_request для проверки, действительно ли обслуживается запрос к REST API. Если вы используете её, убедитесь, что вызываете её после действия parse_request, так как до этого она всегда будет возвращать false.

15 мая 2024 г. 08:58:03
Комментарии

Лучший ответ на данный момент

Kuba Niewiarowski Kuba Niewiarowski
20 сент. 2024 г. 18:52:08
0

Вы можете использовать wp_is_json_request() следующим образом:

if ( wp_is_json_request() ) {
    // выполните здесь ваши действия
}

Убедитесь, что вы установили заголовки Accepts или Content-Type как application/json, иначе wp_is_json_request() вернет false.

Дополнительная документация: https://developer.wordpress.org/reference/functions/wp_is_json_request/

5 нояб. 2022 г. 11:03:28