is_rest ()와 같은 것이 존재합니까?


18

REST API로 조금 시작하고 있습니다. 내가 완전히 오도하지 않으면 initREST API 요청시 작업 후크도 실행됩니다. 이제 REST API 요청이 아닌 일부 코드 만 실행하고 싶습니다.

그래서 나는 같은 is_rest()것을하기 위해 같은 명령을 찾고있었습니다.

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

그러나 나는 이런 것을 찾을 수 없었다. 거기 is_rest()밖으로있다?


1
REST 요청이 아닌 경우 수행하려는 작업을 자세히 설명 할 수 있습니까? 요청의 유형은 쿼리 구문 분석이 끝날 때까지 결정되지 않습니다 init. 또한 API의 일부는 REST 요청이 아닌 요청에 대해 내부적으로 사용될 수 있으므로 해당 탐지에 의존하는 경우 무언가를 깨뜨릴 위험이 있습니다.
— Milo

둘 다 감사합니다. @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 에 (Daniel Bachhuber의) 제안이 WP_Query::is_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가 WordPress 사이트의 Rest API URL에 속하는 경우 Rest API 요청이라는 가정하에 간단한 사용자 정의 함수를 작성했습니다.

유효한 엔드 포인트인지 인증 된 것인지 여부는이 기능이 결정할 수 없습니다. 문제는 이것입니다 : URL이 잠재적 인 Rest API URL입니까?

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']IS가 제대로 채워지지,이 기능은 여전히 반환 false에 관계없이.

URL의 하드 코딩이 없으므로 어떤 이유로 든 API URL 기반을 변경하면 이것이 적용됩니다.


3

어쩌면 옳지 않지만 결국

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

이것이 옳지 않은지 알려주십시오. https://gitlab.com/ripp.io/wordpress/plugin-starter : 공유 할 유용한 플러그인 스타터를 만들려고


1
꽤 퍼머 링크가 활성화되어 있지 않으면 이것이 실패 할 것이라고 생각합니다.
— websupporter 2016 년

당신은 확실히 맞습니다
— Charly

좋아, 꽤 permalink가 필요합니다 ...하지만 누가 그것을 원하지 않습니다! 이것은 가장 안전한 방법입니다. 다른 모든 솔루션은 훌륭하지만 나중에 wp 버전에서 코드를 계속 실행하려면 시간이 지남에 따라 ... 이것은 안전한 방법입니다 !!
— Antony Gibbs

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 );
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.