我从REST API开始。如果我没有完全误导,则init
在其REST API请求时也会执行动作挂钩。现在,我只想在不是REST API请求时执行一些代码。
所以我在寻找类似is_rest()
的命令以便做类似的事情
<?php
if( ! is_rest() ) echo 'no-rest-request';
?>
但是我找不到这样的东西。有is_rest()
外面吗?
我从REST API开始。如果我没有完全误导,则init
在其REST API请求时也会执行动作挂钩。现在,我只想在不是REST API请求时执行一些代码。
所以我在寻找类似is_rest()
的命令以便做类似的事情
<?php
if( ! is_rest() ) echo 'no-rest-request';
?>
但是我找不到这样的东西。有is_rest()
外面吗?
Answers:
刚刚偶然发现了相同的问题,并编写了一个简单的函数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;
}
}
参考文献:
为了解决这个问题,我基于一个假设编写了一个简单的自定义函数,即如果所请求的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库,这将适应。
也许不对,但我最终还是
if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
// Cool API stuff here
}
如果这不正确,请随时告诉我。尝试制作一个有用的插件入门工具以最终共享:https : //gitlab.com/ripp.io/wordpress/plugin-starter
这里确实有两个选择,
REST_REQUEST
已定义。rest_api_init
您想勾入的位置init
。这是我想出的:
/**
* 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 );
}
init
。还要注意,API的各个部分可以在不是REST请求的请求上内部使用,因此如果您依赖该检测,则可能会破坏某些内容。