各位观众,下午好!今天,我们要扒一扒 WordPress 的 get_rest_url()
函数,看看它到底是如何变戏法,生成 REST API 的根 URL 的。准备好来一场源码探险了吗?系好安全带,我们出发!
1. 什么是 REST API 根 URL?为啥它这么重要?
在开始之前,先明确一下概念。REST API (Representational State Transfer Application Programming Interface) 简单来说,就是一套设计风格,让不同的应用之间可以通过 HTTP 协议互相交流。而根 URL,就是这套 API 的入口,就像一个网站的主页,你得先知道主页地址,才能访问里面的各种内容。
例如,WordPress 的 REST API 根 URL 可能是这样的:https://example.com/wp-json/
。有了这个地址,你就可以用它来获取文章列表、创建新文章、更新用户信息等等。
没有根 URL,就像没有地图的寻宝游戏,你根本不知道从哪里开始。所以,get_rest_url()
才会如此重要。
2. get_rest_url()
的真面目:从源码看起
好了,废话不多说,直接上代码!get_rest_url()
函数的代码位于 wp-includes/rest-api.php
文件中。我们来仔细看看它的庐山真面目:
/**
* Retrieves the REST API URL.
*
* @since 4.4.0
*
* @param string $path Optional. REST route. Default empty.
* @param string $scheme Optional. URL scheme context to generate.
* Options are 'rest', 'admin', 'login', 'http', 'https',
* 'relative'. Default 'rest'.
* @return string REST API URL.
*/
function get_rest_url( $path = null, $scheme = 'rest' ) {
$url = home_url( '', $scheme );
if ( empty( $path ) ) {
return trailingslashit( $url . rest_get_url_prefix() );
}
return trailingslashit( $url . rest_get_url_prefix() . '/' . ltrim( $path, '/' ) );
}
看起来是不是没那么可怕?我们一行一行来分析:
/** ... */
:这是 PHPDoc 风格的注释,说明了这个函数的作用、参数和返回值。function get_rest_url( $path = null, $scheme = 'rest' )
:定义了函数get_rest_url()
,它接受两个参数:$path
:可选参数,REST 路由,也就是 API 路径。默认值是null
,表示获取根 URL。$scheme
:可选参数,URL 协议类型,用于生成 URL。默认值是rest
。
$url = home_url( '', $scheme );
:这行代码调用了home_url()
函数,获取站点首页的 URL。home_url()
的第二个参数$scheme
决定了使用哪种协议(http 或 https)。if ( empty( $path ) ) { ... }
:判断$path
是否为空。如果为空,说明我们只需要获取根 URL。return trailingslashit( $url . rest_get_url_prefix() );
:如果$path
为空,这行代码将首页 URL 和 REST API 的 URL 前缀拼接起来,然后用trailingslashit()
函数在末尾添加一个斜杠。rest_get_url_prefix()
函数我们稍后会详细讲解。return trailingslashit( $url . rest_get_url_prefix() . '/' . ltrim( $path, '/' ) );
:如果$path
不为空,这行代码将首页 URL、REST API 的 URL 前缀和$path
拼接起来,同样用trailingslashit()
函数在末尾添加一个斜杠。ltrim( $path, '/' )
用于移除$path
开头的斜杠,避免出现多个连续的斜杠。
3. home_url()
的作用:找到你的家!
在 get_rest_url()
函数中,home_url()
扮演着非常重要的角色。它负责找到你网站的“家”,也就是首页的 URL。让我们来看看 home_url()
的源码(位于 wp-includes/link-template.php
):
/**
* Retrieves the URL for the current site where the front end is displayed.
*
* @since 2.2.0
*
* @param string $path Optional. Path relative to the home URL. Default empty.
* @param string $scheme Optional. Scheme to use. Default is the 'default' scheme.
* See set_url_scheme() for accepted values.
* @return string Home URL of the site.
*/
function home_url( $path = '', $scheme = null ) {
return get_home_url( null, $path, $scheme );
}
实际上,home_url()
只是简单地调用了 get_home_url()
函数。这样做的好处是,可以将逻辑集中在 get_home_url()
中,方便维护和扩展。
我们再深入 get_home_url()
的源码:
/**
* Retrieves the home URL for the current site.
*
* Returns the 'home' option with the appropriate protocol.
*
* @since 3.0.0
*
* @param int|null $blog_id Optional. The blog ID. Default null (current blog).
* @param string $path Optional. Path relative to the home URL. Default empty.
* @param string $scheme Optional. Scheme to use. Default is the 'default' scheme.
* See set_url_scheme() for accepted values.
* @return string Home URL of the site.
*/
function get_home_url( $blog_id = null, $path = '', $scheme = null ) {
global $current_site;
if ( empty( $blog_id ) ) {
$blog_id = get_current_blog_id();
}
$orig_scheme = $scheme;
if ( ! is_string( $path ) ) {
$path = '';
}
$home = get_option( 'home' );
if ( ! empty( $path ) && is_string( $path ) && '#' !== substr( $path, 0, 1 ) ) {
$home = trailingslashit( $home );
}
if ( in_array( $scheme, array( 'http', 'https', 'relative' ), true ) ) {
$home = set_url_scheme( $home, $scheme );
} elseif ( 'rest' === $scheme ) {
$home = set_url_scheme( $home, 'https' );
} else {
$home = set_url_scheme( $home );
}
if ( is_ssl() && 'http' === $orig_scheme ) {
$home = str_replace( 'https://', 'http://', $home );
}
$home = untrailingslashit( $home );
return $home . ( ( $path ) ? '/' . ltrim( $path, '/' ) : '' );
}
这下代码量有点多了,但别慌,我们慢慢分析:
$home = get_option( 'home' );
:这行代码从 WordPress 的数据库中获取home
选项的值。home
选项存储了网站的首页 URL。if ( in_array( $scheme, array( 'http', 'https', 'relative' ), true ) ) { ... }
:判断$scheme
是否为http
、https
或relative
。如果是,则调用set_url_scheme()
函数,设置 URL 的协议类型。elseif ( 'rest' === $scheme ) { $home = set_url_scheme( $home, 'https' ); }
:如果$scheme
是rest
,则强制使用https
协议。这是为了保证 REST API 的安全性。else { $home = set_url_scheme( $home ); }
:如果$scheme
不是以上任何值,则使用默认的协议类型。$home = untrailingslashit( $home );
:移除 URL 末尾的斜杠。return $home . ( ( $path ) ? '/' . ltrim( $path, '/' ) : '' );
:将首页 URL 和$path
拼接起来,并返回结果。
简单总结一下,get_home_url()
函数的作用就是:
- 从数据库中获取网站的首页 URL。
- 根据
$scheme
参数,设置 URL 的协议类型。 - 将首页 URL 和
$path
拼接起来,并返回结果。
4. rest_get_url_prefix()
的秘密:API 的身份证
回到 get_rest_url()
函数,我们还剩下一个关键函数没有讲解:rest_get_url_prefix()
。这个函数的作用是获取 REST API 的 URL 前缀,也就是 wp-json
。
/**
* Retrieves the REST API URL prefix.
*
* @since 4.4.0
*
* @return string REST prefix.
*/
function rest_get_url_prefix() {
/**
* Filters the REST API URL prefix.
*
* @since 4.4.0
*
* @param string $prefix URL prefix. Default 'wp-json'.
*/
return apply_filters( 'rest_url_prefix', 'wp-json' );
}
这个函数非常简单,它只是返回一个字符串 'wp-json'
,并通过 apply_filters()
函数提供了一个过滤器 rest_url_prefix
,允许开发者修改 REST API 的 URL 前缀。
这意味着,如果你不喜欢默认的 wp-json
前缀,你可以通过以下代码来修改它:
add_filter( 'rest_url_prefix', function( $prefix ) {
return 'api'; // 将 URL 前缀修改为 'api'
});
这样,你的 REST API 根 URL 就会变成 https://example.com/api/
。
5. trailingslashit()
:斜杠的重要性
在 get_rest_url()
函数中,我们多次看到了 trailingslashit()
函数。这个函数的作用是在 URL 的末尾添加一个斜杠。
/**
* Adds a trailing slash if not trailing slash or URL.
*
* This will remove trailing forward slashes if the string is a URL or path
* with a query string.
*
* @since 3.0.0
*
* @param string $string What to add the trailing slash to.
* @return string String with trailing slash added.
*/
function trailingslashit( $string ) {
return untrailingslashit( $string ) . '/';
}
实际上,trailingslashit()
函数只是简单地调用了 untrailingslashit()
函数,移除 URL 末尾的斜杠,然后再添加一个斜杠。
那么,为什么要添加斜杠呢?这主要是为了规范化 URL,提高可读性。在 Web 开发中,通常建议在目录的 URL 末尾添加斜杠,以区分文件和目录。
6. 组合拳:get_rest_url()
的工作流程
现在,我们已经了解了 get_rest_url()
函数中使用的所有关键函数。让我们来总结一下它的工作流程:
- 获取网站的首页 URL,通过
home_url()
函数实现。home_url
内部调用get_home_url
,从数据库读取home
选项,并根据传入的$scheme
参数设置协议。 - 获取 REST API 的 URL 前缀,通过
rest_get_url_prefix()
函数实现。默认值为wp-json
,可以通过rest_url_prefix
过滤器修改。 - 将首页 URL 和 REST API 的 URL 前缀拼接起来,如果需要,再加上指定的
$path
。 - 使用
trailingslashit()
函数在 URL 末尾添加一个斜杠。 - 返回最终的 REST API URL。
7. 举个栗子:实际应用场景
假设你的 WordPress 网站的 URL 是 https://example.com
,你想获取 REST API 的根 URL,你可以这样调用 get_rest_url()
函数:
$rest_url = get_rest_url();
echo $rest_url; // 输出:https://example.com/wp-json/
如果你想获取文章列表的 URL,你可以这样调用 get_rest_url()
函数:
$posts_url = get_rest_url( 'wp/v2/posts' );
echo $posts_url; // 输出:https://example.com/wp-json/wp/v2/posts/
8. 源码剖析:表格总结
为了方便大家理解,我们用表格来总结一下 get_rest_url()
函数涉及的关键函数:
函数名 | 作用 | 源码位置 |
---|---|---|
get_rest_url() |
获取 REST API 的 URL。 | wp-includes/rest-api.php |
home_url() |
获取网站的首页 URL。 | wp-includes/link-template.php |
get_home_url() |
获取网站的首页 URL (实际执行函数)。 | wp-includes/link-template.php |
rest_get_url_prefix() |
获取 REST API 的 URL 前缀(默认为 wp-json )。 |
wp-includes/rest-api.php |
trailingslashit() |
在 URL 末尾添加斜杠。 | wp-includes/formatting.php |
set_url_scheme() |
设置 URL 的协议类型(http 或 https)。 | wp-includes/functions.php |
get_option() |
从 WordPress 数据库中获取选项的值。 | wp-includes/option.php |
is_ssl() |
检查当前请求是否使用了 SSL (HTTPS)。 | wp-includes/functions.php |
ltrim() |
移除字符串开头的指定字符(默认为空格)。 | PHP 内置函数 |
untrailingslashit() |
移除字符串末尾的斜杠。 | wp-includes/formatting.php |
apply_filters() |
应用过滤器,允许修改函数返回值。 | wp-includes/plugin.php |
9. 总结:掌握 get_rest_url()
,玩转 WordPress REST API
通过今天的讲解,相信大家对 get_rest_url()
函数的实现原理有了更深入的理解。掌握了这个函数,你就掌握了 WordPress REST API 的入口,可以更轻松地开发基于 WordPress 的应用。
记住,阅读源码是提升编程技能的有效途径。希望今天的探险之旅对你有所帮助!下次再见!