分析 WordPress `is_rest_api_request()` 函数的源码:如何判断当前请求是否为 REST API。

嘿,大家好!我是你们今天的 WordPress REST API 鉴别大师,准备好一起扒一扒 is_rest_api_request() 这个小家伙的老底了吗? 放心,咱们的讲座保证轻松愉快,不会让你觉得像在啃教科书。

开场白:REST API 的世界,真真假假

在 WordPress 的世界里,REST API 就像一个双面间谍,它既能隐藏在常规的 WordPress 请求中,又能独立门户,发起自己的请求。因此,我们需要一双火眼金睛,准确识别出哪些请求是 REST API 的真身。is_rest_api_request() 函数就是我们手中的秘密武器。

第一部分:is_rest_api_request() 的源码解剖

闲话少说,直接上代码,让我们一起深入 wp-includes/functions.php 看看 is_rest_api_request() 的真面目:

/**
 * Determines whether the current request is a REST API request.
 *
 * @since 4.4.0
 *
 * @return bool True if it's a REST API request, false otherwise.
 */
function is_rest_api_request() {
    /**
     * Filters whether the current request is a REST API request.
     *
     * @since 5.5.0
     *
     * @param bool $is_rest_api_request Whether the current request is a REST API request.
     */
    $is_rest_api_request = apply_filters( 'is_rest_api_request', defined( 'REST_REQUEST' ) && REST_REQUEST );

    return $is_rest_api_request;
}

怎么样,是不是比想象中简单? 别被它简洁的外表迷惑了,这里面可是藏着不少玄机。

  • defined( 'REST_REQUEST' ) && REST_REQUEST: 这是判断的核心。它首先检查是否定义了 REST_REQUEST 常量,并且该常量的值是否为 true
  • apply_filters( 'is_rest_api_request', ... ): 这是一个 WordPress 钩子(Hook)。允许其他插件或主题修改 is_rest_api_request() 的返回值。这为开发者提供了极大的灵活性。

第二部分: REST_REQUEST 常量:REST API 的身份证

REST_REQUEST 常量就像 REST API 请求的身份证。当 WordPress 接收到一个请求时,如果它认为这个请求是 REST API 请求,就会定义 REST_REQUEST 常量,并将其设置为 true

那么,WordPress 是如何判断一个请求是否是 REST API 请求的呢? 这就涉及到 WordPress 的路由机制了。简单来说,WordPress 会检查请求的 URL,看它是否符合 REST API 的 URL 规则。

REST API 的 URL 通常以 /wp-json/ 开头。例如:

  • https://example.com/wp-json/wp/v2/posts (获取所有文章)
  • https://example.com/wp-json/wp/v2/posts/123 (获取 ID 为 123 的文章)

如果请求的 URL 符合这个规则,WordPress 就会定义 REST_REQUEST 常量,并将其设置为 true

第三部分:深入 WordPress 的路由机制

想更深入地了解 REST_REQUEST 是如何被定义的,我们需要稍微了解一下 WordPress 的路由机制。

WordPress 使用 WP_Rewrite 类来处理 URL 重写和路由。当一个请求到达 WordPress 时,WP_Rewrite 会分析请求的 URL,并将其映射到相应的 WordPress 组件(例如,文章、页面、分类等)。

对于 REST API 请求,WordPress 会使用 rest_api_loaded 钩子来注册 REST API 的路由。rest_api_loaded 钩子会在 WordPress 加载 REST API 组件后被触发。

以下代码片段展示了 WordPress 如何注册 REST API 的路由:

add_action( 'rest_api_init', 'create_initial_rest_routes', 0 );

create_initial_rest_routes 函数会注册 WordPress 核心的 REST API 路由,例如文章、页面、分类等。

当一个请求到达 WordPress 时,如果它符合某个已注册的 REST API 路由,WordPress 就会定义 REST_REQUEST 常量,并将其设置为 true

第四部分:apply_filters 钩子:灵活的开关

apply_filters( 'is_rest_api_request', ... ) 钩子为开发者提供了修改 is_rest_api_request() 返回值的机会。这意味着你可以根据自己的需求,自定义判断一个请求是否是 REST API 请求的规则。

例如,你可以创建一个插件,根据请求的 HTTP 方法(例如,GET、POST、PUT、DELETE)来判断是否是 REST API 请求。

以下代码片段展示了如何使用 apply_filters 钩子来修改 is_rest_api_request() 的返回值:

add_filter( 'is_rest_api_request', 'my_custom_rest_api_check' );

function my_custom_rest_api_check( $is_rest_api_request ) {
    if ( $_SERVER['REQUEST_METHOD'] === 'POST' && strpos( $_SERVER['REQUEST_URI'], '/my-custom-api/' ) !== false ) {
        $is_rest_api_request = true;
    }

    return $is_rest_api_request;
}

在这个例子中,如果请求的 HTTP 方法是 POST,并且请求的 URL 包含 /my-custom-api/my_custom_rest_api_check 函数就会将 is_rest_api_request 设置为 true

第五部分:实战演练:如何使用 is_rest_api_request()

现在我们已经了解了 is_rest_api_request() 的原理,让我们来看一些实际的例子,看看如何在代码中使用它。

  • 在插件中判断是否是 REST API 请求
if ( is_rest_api_request() ) {
    // 这是 REST API 请求,执行相应的操作
    // 例如,验证用户权限,处理请求数据,返回 JSON 响应
} else {
    // 这不是 REST API 请求,执行其他操作
    // 例如,渲染 HTML 页面,处理表单提交
}
  • 在主题中判断是否是 REST API 请求
if ( is_rest_api_request() ) {
    // 这是 REST API 请求,不渲染主题模板
    exit;
} else {
    // 这不是 REST API 请求,渲染主题模板
    get_header();
    // ...
    get_footer();
}
  • 自定义 REST API 端点

在自定义 REST API 端点中,通常不需要显式地调用 is_rest_api_request(),因为 WordPress 会自动处理 REST API 请求。但是,你可以使用它来执行一些额外的检查,例如验证用户权限。

add_action( 'rest_api_init', function () {
  register_rest_route( 'my-plugin/v1', '/my-endpoint', array(
    'methods'  => 'GET',
    'callback' => 'my_endpoint_callback',
    'permission_callback' => function () {
            if ( ! is_user_logged_in() ) {
                return new WP_Error( 'rest_not_logged_in',
                    'You are not currently logged in.',
                    array( 'status' => 401 ) );
            }
      return true;
    }
  ) );
} );

function my_endpoint_callback( WP_REST_Request $request ) {
  // 这里不需要判断 is_rest_api_request(),因为这个函数只会在 REST API 请求中被调用
  $items = array();

  return rest_ensure_response( $items );
}

第六部分:常见问题解答 (FAQ)

  • 为什么我的 REST API 请求没有定义 REST_REQUEST 常量?

    • 请检查你的 REST API URL 是否正确。
    • 请确保你的 WordPress 版本支持 REST API (4.4 及以上)。
    • 请检查是否有其他插件或主题冲突,导致 REST API 路由无法正常注册。
  • 我可以使用 is_admin() 函数来判断是否是 REST API 请求吗?

    • 不建议这样做。is_admin() 函数用于判断是否是 WordPress 后台请求,而不是 REST API 请求。REST API 请求可能发生在后台,也可能发生在前端。
  • 我应该在哪里使用 is_rest_api_request() 函数?

    • 你可以在任何需要判断是否是 REST API 请求的地方使用 is_rest_api_request() 函数。例如,在插件、主题、自定义代码中。

第七部分:总结

is_rest_api_request() 函数是 WordPress 中一个非常重要的函数,它可以帮助我们判断当前请求是否是 REST API 请求。通过深入了解它的源码和原理,我们可以更好地利用 REST API 来构建强大的 WordPress 应用。

表格总结:is_rest_api_request() 关键信息

特性 描述
函数定义 function is_rest_api_request() (位于 wp-includes/functions.php)
返回值 bool (true 或 false)
核心判断 defined( 'REST_REQUEST' ) && REST_REQUEST
REST_REQUEST 常量,当请求被识别为 REST API 请求时,由 WordPress 定义并设置为 true
apply_filters apply_filters( 'is_rest_api_request', ... ) 允许开发者通过钩子修改函数的返回值,提供自定义判断逻辑。
使用场景 插件、主题、自定义代码中,需要区分 REST API 请求和普通请求的场合。例如,根据请求类型执行不同的操作,避免主题模板渲染,验证用户权限等。
注意事项 检查 REST API URL 是否正确,确认 WordPress 版本支持 REST API,排除插件或主题冲突。 不建议使用 is_admin() 代替 is_rest_api_request()

希望今天的讲座对你有所帮助! 记住,理解代码的最好方法就是动手实践。 赶紧去你的 WordPress 项目中试试 is_rest_api_request() 吧! 如果还有什么问题,随时来找我,咱们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注