Có cái gì đó như is_rest () tồn tại không


16

Tôi đang bắt đầu một chút với API REST. Nếu tôi không hoàn toàn đánh lừa, inithook hành động cũng được thực thi khi yêu cầu API REST. Bây giờ, tôi chỉ muốn thực thi một số mã, khi đó không phải là yêu cầu API REST.

Vì vậy, tôi đã tìm kiếm một lệnh như is_rest()để làm một cái gì đó như

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

Nhưng tôi không thể tìm thấy thứ gì đó như thế này. Có một cái is_rest()đó không?


1
Có lẽ bạn có thể giải thích những gì bạn muốn làm khi đó không phải là yêu cầu REST? Loại yêu cầu không được xác định cho đến khi phân tích cú pháp truy vấn, xảy ra sau init. Cũng lưu ý rằng các phần của API có thể được sử dụng nội bộ cho các yêu cầu không phải là yêu cầu REST, vì vậy bạn có nguy cơ phá vỡ thứ gì đó nếu bạn đang dựa vào phát hiện đó.
Milo

Cảm ơn rất nhiều cả hai bạn. @birgire: Bạn có thể đăng bài này dưới dạng câu trả lời không, vì vậy tôi có thể kiểm tra nó. Về cơ bản, nó là câu trả lời cho câu hỏi của tôi :)
hỗ trợ web

Câu trả lời:


14

Đó là một điểm tốt của @Milo, REST_REQUESThằng số được định nghĩatrue, bên trong rest_api_loaded()nếu $GLOBALS['wp']->query_vars['rest_route']không trống.

Nó được nối vào parse_requestthông qua:

add_action( 'parse_request', 'rest_api_loaded' );

nhưng parse_requestkích hoạt muộn hơn init- Xem ví dụ về Codex tại đây .

Có một gợi ý (của Daniel Bachhuber) trong vé số 34373 liên quan WP_Query::is_rest(), nhưng nó đã bị hoãn / hủy.


10

Chỉ cần vấp phải cùng một vấn đề và đã viết một hàm đơn giản is_restcho phép bạn kiểm tra xem yêu cầu hiện tại có phải là yêu cầu API WP REST không.

<?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;
    }
}

Người giới thiệu:


4

Để giải quyết vấn đề này, tôi đã viết một hàm tùy chỉnh đơn giản dựa trên giả định rằng nếu URI được yêu cầu nằm trong URL API nghỉ của trang web WordPress, thì nó sẽ tuân theo yêu cầu API nghỉ ngơi.

Cho dù đó là điểm cuối hợp lệ hay được xác thực, không phải là chức năng này để xác định. Câu hỏi đặt ra là: URL có phải là url Rest API tiềm năng không?

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;
}

Nếu bạn $_SERVER['REQUEST_URI']không được điền đúng, chức năng này vẫn sẽ trở lại false, bất kể.

Không có mã hóa cứng của URL vì vậy nếu bạn vì một số lý do thay đổi cơ sở URL API của mình, điều này sẽ thích nghi.


2

Có lẽ không đúng, nhưng tôi đã kết thúc với

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

Hãy cho tôi biết nếu điều này không đúng. Cố gắng tạo một trình khởi động plugin hữu ích để cuối cùng chia sẻ: https://gitlab.com/ripp.io/wordpress/plugin-starter


1
Tôi nghĩ, điều này sẽ thất bại, nếu bạn không có hoạt động permalinks đẹp.
hỗ trợ web

Bạn chắc chắn đúng
Charly

Ok nó đòi hỏi khá nhiều permalink ... nhưng ai không muốn nó !!!? Đây dường như là cách an toàn nhất để làm điều này. Tất cả các giải pháp khác đều lạ mắt nhưng theo thời gian nếu bạn muốn mã của mình vẫn chạy trên các phiên bản wp sau này ... thì đây có vẻ là một cách an toàn cho tôi !!
Antony Gibbs

1

Hai lựa chọn ở đây thực sự,

  1. Kiểm tra nếu REST_REQUESTđược xác định.
  2. Móc vào rest_api_initnơi bạn muốn móc vào init.

0

Đây là những gì tôi nghĩ ra:

/**
 * 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_requestMặc dù vậy, tôi không có nhiều thời gian để xem xét việc CLI phát hiện các yêu cầu REST trước khi hành động được thực hiện. Tôi đang mở để đề xuất!

Tôi vẫn chưa viết một số bài kiểm tra xung quanh tính năng này, tôi sẽ cập nhật câu trả lời này một khi tôi làm.

-- Biên tập

Chỉ cần tìm cách WooC Commerce xử lý việc này. WooC Commerce dường như không tính đến các permalinks đơn giản:

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 );
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.