Чи існує щось на зразок is_rest ()


18

Починаю трохи з API REST. Якщо мене не вводять в оману, initгак дії також виконується, коли його REST API-запит. Тепер я хочу виконати якийсь код лише тоді, коли це не запит REST API.

Тому я шукав таку команду is_rest(), щоб зробити щось подібне

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

Але я не могла знайти щось подібне. Є is_rest()там?


1
Можливо, ви можете детальніше розібратися, що ви хочете зробити, коли це не REST-запит? Тип запиту не визначається до розбору запитів, що відбувається після init. Також зауважте, що частини API можна використовувати внутрішньо для запитів, які не є REST-запитами, тому ви ризикуєте щось зламати, якщо ви покладаєтесь на це виявлення.
— Міло,

Дякую вам обом. @birgire: Чи можете ви опублікувати це як відповідь, щоб я міг це перевірити. В основному, це відповідь на моє запитання :)
— websupporter

Відповіді:


14

Це хороша точка від @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- Дивіться, наприклад, Кодекс тут .

У квитку № 34373 була пропозиція (Даніель Бахубер) щодо WP_Query::is_rest(), але її було відкладено / скасовано.


# 42061 може додати wp_is_rest_request()або wp_doing_rest().
— Ян Данн

11

Просто наткнувся на ту ж проблему і написав просту функцію, is_restяка дозволяє перевірити, чи поточний запит є WP REST API-запитом.

<?php
if ( !function_exists( 'is_rest' ) ) {
    /**
     * Checks if the current request is a WP REST API request.
     *
     * Case #1: After WP_REST_Request initialisation
     * Case #2: Support "plain" permalink settings
     * Case #3: It can happen that WP_Rewrite is not yet initialized,
     *          so do this (wp-settings.php)
     * Case #4: URL Path begins with wp-json/ (your REST prefix)
     *          Also supports WP installations in subfolders
     *
     * @returns boolean
     * @author matzeeable
     */
    function is_rest() {
        $prefix = rest_get_url_prefix( );
        if (defined('REST_REQUEST') && REST_REQUEST // (#1)
                || isset($_GET['rest_route']) // (#2)
                        && strpos( trim( $_GET['rest_route'], '\\/' ), $prefix , 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;
    }
}

Список літератури:


4

Щоб вирішити цю проблему, я написав просту функцію користувача, засновану на припущенні, що якщо запитуваний URI потрапляє під URL-адресу API відпочинку WordPress, то випливає, що це запит API відпочинку.

Чи це дійсна кінцева точка, чи автентифікація, ця функція не визначає. Питання таке: чи URL-адреса є потенційним URL-адресою 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, вона адаптується.


3

Можливо, не так, але я закінчив

if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
    // Cool API stuff here
}

Сміливо повідомте мене, якщо це неправильно. Намагаючись зробити корисний запуск плагіну, щоб згодом поділитися: https://gitlab.com/ripp.io/wordpress/plugin-starter


1
Я думаю, це не вдасться, якби у вас не було активних постійних посилань.
— прихильник

Ви напевно правильні
— Чарлі

Гаразд, це вимагає досить постійної посилання ... але хто цього не хоче !!!? Це мені здається найбезпечнішим способом це зробити. Всі інші рішення фантазії, але з часом, якщо ви хочете, щоб ваш код все ще працював на пізніших версіях wp ... це здається мені безпечним способом !!
— Антоні Гіббс

1

Тут дійсно два варіанти,

  1. Перевірте, чи REST_REQUESTвизначено.
  2. Зачепити rest_api_initтуди, куди ти хотів зачепитись init.

0

Ось що я придумав:

/**
 * Determines if the current request we are handling is a REST Request.
 * This function can be called even on mu-plugins.
 *
 * You might want to prefix this function name with
 * something more unique to your project.
 *
 * @return bool
 */
function is_rest(): bool {
    $is_cli              = php_sapi_name() === 'cli';
    $permalink_structure = get_option( 'permalink_structure' );
    $rest_prefix         = rest_get_url_prefix();

    if ( ! empty( $permalink_structure ) && ! $is_cli ) {
        /*
         * HTTP request with Pretty Permalinks.
         */
        if ( substr( $_SERVER['REQUEST_URI'], 0, strlen( $rest_prefix ) ) === $rest_prefix ) {
            return true;
        }
    } elseif ( empty( $permalink_structure ) && ! $is_cli ) {
        /*
         * HTTP Requests with Plain Permalinks
         *
         * We can rely on "?rest_route" for plain permalinks, this value don't change:
         * wp/wp-includes/rest-api.php:145
         *
         * All ?rest_route must start with "/":
         * wp/wp-includes/rest-api.php:159
         */
        if ( isset( $_GET['rest_route'] ) && substr( $_GET['rest_route'], 0, 1 ) === '/' ) {
            return true;
        }
    } elseif ( $is_cli ) {
        /*
         * CLI request
         */
        if ( did_action( 'parse_request' ) ) {
            return defined( 'REST_REQUEST' ) && REST_REQUEST;
        } else {
            throw new RuntimeException( "Maybe someone at StackOverflow can help fill this gap of identifying REST requests on CLI before the parse_request action has fired and the REST_REQUEST constant is available?" );
        }
    }

    return false;
}

parse_requestОднак у мене не було багато часу, щоб розібратися з тим, щоб CLI виявляв REST-запити до початку дії. Я відкритий для пропозицій!

Я ще мушу написати кілька тестів навколо цієї функції, я оновлю цю відповідь, як тільки це зробити.

- Редагувати

Щойно з’ясували, як WooCommerce справляється з цим. Схоже, WooCommerce не враховує звичайні посилання:

public function is_rest_api_request() {
    if ( empty( $_SERVER['REQUEST_URI'] ) ) {
        return false;
    }

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

    return apply_filters( 'woocommerce_is_rest_api_request', $is_rest_api_request );
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.