剖析 WordPress `rest_get_json_url()` 函数的源码:如何获取文章或分类的 REST API URL。

各位观众,晚上好!我是今晚的客座讲师,今天咱们来聊聊 WordPress 的 rest_get_json_url() 函数,这个函数看着不起眼,但却是我们构建现代化 WordPress 应用,特别是 headless WordPress 的一把瑞士军刀。它能帮你轻松获取文章、分类甚至自定义内容类型的 REST API URL,简直是懒人福音,效率神器。

废话不多说,直接进入正题。

rest_get_json_url() 是干嘛的?

简单来说,rest_get_json_url() 函数返回一个 JSON 格式的 REST API 端点的 URL。 这对于从 JavaScript 或者其他外部应用访问 WordPress 数据至关重要。 想象一下,你想用 React 写一个博客前端,总不能直接访问数据库吧? 这时候,REST API 就派上用场了,而 rest_get_json_url() 就是生成这些 API 链接的钥匙。

源码剖析:扒开它的神秘面纱

要理解 rest_get_json_url() 的威力,咱们得先看看它的源码(WordPress 核心代码通常藏得很深,但别怕,我们来把它挖出来)。

/**
 * Retrieves the URL to a JSON schema for a post or taxonomy.
 *
 * @since 4.4.0
 *
 * @param WP_Post|WP_Term|string|null $object Optional. Post, term, or schema ID. Default null.
 * @return string URL to the JSON schema.
 */
function rest_get_json_schema_url( $object = null ) {
    if ( is_string( $object ) ) {
        $schema_id = $object;
    } elseif ( $object instanceof WP_Post ) {
        $schema_id = 'post-' . $object->post_type;
    } elseif ( $object instanceof WP_Term ) {
        $schema_id = 'term-' . $object->taxonomy;
    } else {
        $schema_id = 'core';
    }

    /**
     * Filters the URL to a JSON schema.
     *
     * @since 4.4.0
     *
     * @param string $url       URL to the JSON schema.
     * @param string $schema_id Schema ID.
     * @param mixed  $object    Post, term, or schema ID.
     */
    return apply_filters( 'rest_url_prefix', rest_url( 'wp/v2/schemas/' . $schema_id ), $schema_id, $object );
}

/**
 * Retrieves the URL to a REST endpoint.
 *
 * @since 4.4.0
 *
 * @param string $path Optional. REST route. Default '/'.
 * @return string REST URL.
 */
function rest_url( $path = '/' ) {
    global $wp_rewrite;

    if ( get_option( 'permalink_structure' ) ) {
        if ( ! preg_match( '#^/#', $path ) ) {
            $path = '/' . $path;
        }

        $url = trailingslashit( get_home_url() ) . rest_get_route_prefix() . $path;
    } else {
        $url = add_query_arg( 'rest_route', $path, get_home_url() );
    }

    /**
     * Filters the REST URL.
     *
     * @since 4.4.0
     *
     * @param string $url  REST URL.
     * @param string $path REST route.
     */
    return apply_filters( 'rest_url', $url, $path );
}

/**
 * Retrieves the REST route prefix.
 *
 * @since 4.7.0
 *
 * @return string The REST prefix. Default 'wp-json'.
 */
function rest_get_route_prefix() {
    /**
     * Filters the REST route prefix.
     *
     * @since 4.7.0
     *
     * @param string $prefix The REST prefix.
     */
    return apply_filters( 'rest_route_prefix', 'wp-json' );
}

稍微解释一下:

  1. rest_url() 函数: 这个是核心函数,它根据你的 WordPress 固定链接设置(permalink structure)来构建 REST API 的基础 URL。如果你的固定链接是美化过的(比如 /blog/%postname%/ ),它会把 REST API 的路径添加到你的网站根 URL 后面。 如果你的固定链接是默认的(?p=123 这种),它会使用 add_query_arg()rest_route 参数添加到 URL 上。

  2. rest_get_route_prefix() 函数: 这个函数返回 REST API 的前缀,默认是 wp-json。 你可以通过 rest_route_prefix 过滤器来修改这个前缀。 修改这个前缀可以增加安全性,防止别人轻易猜到你的 REST API 端点。

  3. rest_get_json_schema_url() 函数: 虽然名字是 schema_url,但它实际上是用来构造 REST API URL 的基础。它根据传入的对象(文章、分类等)来确定 API 的路径。

现在,我们来模拟一下 rest_get_json_url() 的行为,自己写一个类似的函数(当然,实际使用中直接用 WordPress 提供的就好了):

function my_rest_get_json_url( $object_type, $object_id = null ) {
    $prefix = apply_filters( 'rest_route_prefix', 'wp-json' ); // 获取 REST API 前缀
    $home_url = get_home_url(); // 获取网站根 URL
    $permalink_structure = get_option( 'permalink_structure' ); // 获取固定链接设置

    $path = '/' . $prefix . '/wp/v2/'; // REST API 的基本路径

    switch ( $object_type ) {
        case 'posts':
            $path .= 'posts';
            if ( $object_id ) {
                $path .= '/' . $object_id;
            }
            break;
        case 'pages':
            $path .= 'pages';
            if ( $object_id ) {
                $path .= '/' . $object_id;
            }
            break;
        case 'categories':
            $path .= 'categories';
            if ( $object_id ) {
                $path .= '/' . $object_id;
            }
            break;
        // 可以添加更多对象类型,比如自定义文章类型、标签等
        default:
            return null; // 不支持的对象类型
    }

    if ( $permalink_structure ) {
        $url = trailingslashit( $home_url ) . ltrim( $path, '/' ); // 使用固定链接
    } else {
        $url = add_query_arg( 'rest_route', $path, $home_url ); // 使用查询参数
    }

    return apply_filters( 'my_rest_api_url', $url, $object_type, $object_id ); // 允许过滤 URL
}

// 使用示例:
$post_url = my_rest_get_json_url( 'posts', 123 ); // 获取 ID 为 123 的文章的 REST API URL
$category_url = my_rest_get_json_url( 'categories', 45 ); // 获取 ID 为 45 的分类的 REST API URL
$all_posts_url = my_rest_get_json_url( 'posts' ); // 获取所有文章的 REST API URL

echo "Post URL: " . $post_url . "<br>";
echo "Category URL: " . $category_url . "<br>";
echo "All Posts URL: " . $all_posts_url . "<br>";

这个 my_rest_get_json_url() 函数模仿了 rest_get_json_url() 的行为,可以根据对象类型和 ID 生成 REST API URL。它考虑了固定链接设置,并允许你通过 my_rest_api_url 过滤器来修改生成的 URL。

如何使用 rest_get_json_url() 获取不同类型数据的 REST API URL

rest_get_json_url() 并不是直接调用的函数,而是 rest_urlrest_get_route_prefix 以及一些其他函数的组合。要获取文章、分类等数据的 REST API URL,通常需要结合其他函数和一些逻辑。以下是一些常用的方法:

  • 获取文章的 REST API URL:

    $post_id = 123; // 替换成实际的文章 ID
    $post_url = get_rest_url( null, '/wp/v2/posts/' . $post_id );
    echo "Post URL: " . $post_url;

    或者,如果你已经有了 WP_Post 对象:

    $post = get_post( 123 ); // 替换成实际的文章 ID
    $post_url = get_rest_url( null, '/wp/v2/posts/' . $post->ID );
    echo "Post URL: " . $post_url;
  • 获取所有文章的 REST API URL:

    $all_posts_url = get_rest_url( null, '/wp/v2/posts' );
    echo "All Posts URL: " . $all_posts_url;
  • 获取分类的 REST API URL:

    $category_id = 45; // 替换成实际的分类 ID
    $category_url = get_rest_url( null, '/wp/v2/categories/' . $category_id );
    echo "Category URL: " . $category_url;
  • 获取所有分类的 REST API URL:

    $all_categories_url = get_rest_url( null, '/wp/v2/categories' );
    echo "All Categories URL: " . $all_categories_url;
  • 获取自定义文章类型 (Custom Post Type) 的 REST API URL:

    假设你的自定义文章类型是 products

    $product_id = 789; // 替换成实际的产品 ID
    $product_url = get_rest_url( null, '/wp/v2/products/' . $product_id );
    echo "Product URL: " . $product_url;
    
    $all_products_url = get_rest_url( null, '/wp/v2/products' );
    echo "All Products URL: " . $all_products_url;

get_rest_url() 函数

上面的例子中,我们使用了 get_rest_url() 函数。 这个函数是 WordPress 4.7 引入的,它实际上是对 rest_url() 函数的封装,使用起来更方便。

/**
 * Retrieves a REST URL.
 *
 * @since 4.7.0
 *
 * @param int|null   $blog_id Optional. Blog ID. Default null.
 * @param string     $path    Optional. REST route. Default '/'.
 * @return string REST URL.
 */
function get_rest_url( $blog_id = null, $path = '/' ) {
    switch_to_blog( get_current_blog_id() );

    $url = rest_url( $path );

    restore_current_blog();

    return $url;
}

简单来说,get_rest_url() 帮你处理了多站点环境下的 URL 生成,如果你不在多站点环境下,可以简单地认为它和 rest_url() 的作用是一样的。

自定义 REST API URL:使用过滤器

WordPress 提供了强大的过滤器系统,允许你修改几乎任何东西,包括 REST API URL。 你可以使用 rest_url 过滤器来修改整个 REST API 的 URL,或者使用特定于文章类型或分类的过滤器来修改它们的 URL。

例如,你想为所有文章的 REST API URL 添加一个查询参数 debug=true

add_filter( 'rest_url', 'my_custom_rest_url', 10, 2 );

function my_custom_rest_url( $url, $path ) {
    if ( strpos( $path, '/wp/v2/posts' ) !== false ) {
        $url = add_query_arg( 'debug', 'true', $url );
    }
    return $url;
}

// 现在,获取所有文章的 REST API URL:
$all_posts_url = get_rest_url( null, '/wp/v2/posts' );
echo "All Posts URL: " . $all_posts_url; // 输出的 URL 会包含 ?debug=true

总结:rest_get_json_url() 的威力与应用

虽然我们没有直接调用 rest_get_json_url() 函数,但通过分析 rest_urlrest_get_route_prefixget_rest_url 函数,我们了解了如何构建 REST API URL。 理解这些函数对于以下场景至关重要:

  • Headless WordPress 开发: rest_get_json_url() 或者 get_rest_url 是 headless WordPress 的基石,让你能够使用 React、Vue 或 Angular 等前端框架来构建 WordPress 前端。
  • 移动应用开发: 你可以使用 REST API 来从 WordPress 网站获取数据,并在移动应用中显示。
  • 集成其他系统: REST API 允许你将 WordPress 与其他系统(比如 CRM、ERP)集成,实现数据的自动同步和共享。
  • 自定义 REST API 端点: 了解 REST API URL 的构建方式,可以帮助你创建自定义 REST API 端点,满足特定的需求。

表格总结:常用函数和过滤器

函数/过滤器 作用
rest_url() 构建 REST API 的基础 URL,考虑了固定链接设置。
get_rest_url() rest_url() 的封装,简化了多站点环境下的 URL 构建。
rest_get_route_prefix() 获取 REST API 的前缀(默认为 wp-json)。
rest_route_prefix 过滤器 允许你修改 REST API 的前缀。
rest_url 过滤器 允许你修改整个 REST API 的 URL。

注意事项:

  • 权限控制: REST API 默认会返回所有公开的数据。 你需要根据实际情况进行权限控制,确保只有授权用户才能访问敏感数据。
  • 缓存: REST API 的性能非常重要。 你应该使用缓存技术(比如 WordPress 的对象缓存、HTTP 缓存)来提高 REST API 的响应速度。
  • 版本控制: 随着 WordPress 的更新,REST API 可能会发生变化。 你应该使用版本控制(比如 /wp/v2/ 中的 v2)来确保你的代码与特定的 REST API 版本兼容。

好了,今天的讲座就到这里。希望通过今天的讲解,你能对 WordPress 的 rest_get_json_url() 函数以及相关的 REST API URL 构建有更深入的理解。 记住,理解原理比死记硬背函数更重要! 下次再见!

发表回复

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