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상수가되어 정의truerest_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.