是否存在is_rest()之类的东西


18

我从REST API开始。如果我没有完全误导,则init在其REST API请求时也会执行动作挂钩。现在,我只想在不是REST API请求时执行一些代码。

所以我在寻找类似is_rest()的命令以便做类似的事情

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

但是我找不到这样的东西。有is_rest()外面吗?


1
当不是REST请求时,也许您可​​以详细说明您想做什么?直到查询解析(直到之后)才会确定请求的类型init。还要注意,API的各个部分可以在不是REST请求的请求上内部使用,因此如果您依赖该检测,则可能会破坏某些内容。
米洛

非常感谢你们俩。@birgire:可以将其发布为答案,所以我可以检查一下。基本上,这是我的问题的答案:)
websupporter

Answers:


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-例如参见此处的Codex 。

有门票的建议(由丹尼尔·Bachhuber)#34373有关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']填充不正确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

您绝对正确
-Charly

好的,它需要固定的链接...但是谁不想要它!在我看来,这是最安全的方法。所有其他解决方案都是不错的选择,但是随着时间的流逝,如果您希望您的代码仍可以在更高版本的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 );
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.