嘿!大家好!我是你们今天的 WordPress 信息侦探,代号“InfoHound”。咱们今天来聊聊 WordPress 里那个神通广大的 get_bloginfo()
函数,看看它到底是如何从数据库和常量里挖出各种站点信息的。准备好了吗?咱们开始探险!
第一部分:get_bloginfo()
是个啥?
首先,让我们给 get_bloginfo()
来个官方定义:它是一个 WordPress 内置函数,用于检索关于 WordPress 站点的信息,比如站点的名称、描述、URL 等等。你可以把它想象成一个信息检索器,只要告诉它你想知道什么,它就会尽力去找出来。
但是,它可不是像搜索引擎那样瞎搜一气,而是有明确的目标和路径。它主要从两个地方寻找信息:
- 数据库: WordPress 站点的大部分信息都存储在数据库里,比如站点名称、描述、管理员邮箱等等。
- 常量: 有些信息在 WordPress 的配置文件
wp-config.php
中定义为常量,比如 WordPress 的版本号、调试模式等等。
第二部分:get_bloginfo()
的庐山真面目:源码解读
好了,理论知识铺垫完毕,咱们直接上代码,看看 get_bloginfo()
的源码是如何运作的。
function get_bloginfo( string $show = '', string $filter = 'raw' ): string {
global $wpdb, $blog_id, $site_id;
$output = '';
switch ( $show ) {
case 'name':
$output = get_option( 'blogname' );
break;
case 'description':
$output = get_option( 'blogdescription' );
break;
case 'wpurl':
case 'url':
$output = get_option( 'siteurl' );
break;
case 'home':
$output = home_url();
break;
case 'siteurl':
$output = site_url();
break;
case 'admin_email':
$output = get_option( 'admin_email' );
break;
case 'charset':
$output = get_option( 'blog_charset' );
break;
case 'version':
$output = get_blog_version();
break;
case 'html_type':
$output = get_option( 'html_type' );
break;
case 'text_direction':
$output = get_option( 'text_direction' );
break;
case 'language':
$output = get_locale();
break;
case 'stylesheet_url':
$output = get_stylesheet_uri();
break;
case 'stylesheet_directory':
$output = get_stylesheet_directory_uri();
break;
case 'template_url':
case 'template_directory':
$output = get_template_directory_uri();
break;
case 'pingback_url':
$output = get_option( 'pingback_url' );
break;
case 'rss_url':
$output = get_feed_link( 'rss' );
break;
case 'rss2_url':
$output = get_feed_link( 'rss2' );
break;
case 'atom_url':
$output = get_feed_link( 'atom' );
break;
case 'rdf_url':
$output = get_feed_link( 'rdf' );
break;
case 'comments_rss2_url':
$output = get_feed_link( 'comments_rss2' );
break;
default:
$output = '';
break;
}
$output = apply_filters( 'pre_option_' . $show, $output );
$output = apply_filters( 'option_' . $show, $output );
if ( 'raw' === $filter ) {
return $output;
}
return sanitize_text_field( $output );
}
别被这段代码吓到,咱们一步一步来分析。
-
函数签名:
function get_bloginfo( string $show = '', string $filter = 'raw' ): string {
$show
: 这是最重要的参数,它告诉get_bloginfo()
你想获取什么信息。比如,你想获取站点名称,就把$show
设置为'name'
。$filter
: 这个参数用来控制输出结果的过滤方式。默认值是'raw'
,表示不进行任何过滤。如果设置为其他值,可能会对输出结果进行转义或清理。通常情况下,保持默认值就够了。: string
:表示此函数返回一个字符串。
-
全局变量:
global $wpdb, $blog_id, $site_id;
$wpdb
:这是一个全局对象,代表 WordPress 的数据库连接。通过它可以执行 SQL 查询,从数据库中获取数据。$blog_id
和$site_id
:这两个变量在多站点 WordPress 中使用,分别代表当前博客和站点的 ID。
-
switch
语句:switch ( $show ) { case 'name': $output = get_option( 'blogname' ); break; // ... 其他 case ... default: $output = ''; break; }
这是
get_bloginfo()
的核心部分。它使用switch
语句来判断$show
参数的值,并根据不同的值执行不同的操作。case 'name'
: 如果$show
是'name'
,就调用get_option( 'blogname' )
函数来获取站点名称。get_option()
函数是 WordPress 用来从wp_options
表中获取选项值的函数。'blogname'
是存储站点名称的选项名。case 'description'
: 类似地,如果$show
是'description'
,就调用get_option( 'blogdescription' )
来获取站点描述。case 'wpurl'
或'url'
: 这两个 case 获取的是站点的 URL,它们都调用get_option( 'siteurl' )
。case 'home'
: 这个比较特殊,它调用home_url()
函数来获取站点的首页 URL。home_url()
函数会考虑多站点的情况,并返回正确的首页 URL。case 'siteurl'
: 调用site_url()
函数来获取站点的 URL,它和home_url()
类似,会考虑多站点的情况case 'version'
: 这个 case 调用get_blog_version()
函数来获取 WordPress 的版本号。get_blog_version()
函数通常是从wp-includes/version.php
文件中读取版本号常量。default
: 如果$show
的值不在任何一个case
中,就将$output
设置为空字符串。
-
各种URL的获取:
stylesheet_url
: 获取样式表URL,通过get_stylesheet_uri()
获取。stylesheet_directory
: 获取样式表目录的URL,通过get_stylesheet_directory_uri()
获取。template_url
/template_directory
: 获取模板目录URL,通过get_template_directory_uri()
获取。pingback_url
: 获取Pingback URL,通过get_option( 'pingback_url' )
获取。rss_url
,rss2_url
,atom_url
,rdf_url
,comments_rss2_url
: 获取各种RSS Feed URL, 通过get_feed_link()
获取。
-
过滤器(Filters):
$output = apply_filters( 'pre_option_' . $show, $output ); $output = apply_filters( 'option_' . $show, $output );
WordPress 提供了强大的过滤器机制,允许开发者在函数执行过程中修改数据。
apply_filters( 'pre_option_' . $show, $output )
:这个过滤器允许在从数据库中获取选项值之前修改$output
。apply_filters( 'option_' . $show, $output )
:这个过滤器允许在从数据库中获取选项值之后修改$output
。
通过这些过滤器,你可以轻松地自定义
get_bloginfo()
的输出结果。 -
Sanitization:
if ( 'raw' === $filter ) { return $output; } return sanitize_text_field( $output );
如果
$filter
不是'raw'
,就调用sanitize_text_field()
函数来清理$output
。sanitize_text_field()
函数会移除字符串中的 HTML 标签和特殊字符,以防止 XSS 攻击。
第三部分:get_option()
函数:数据库里的寻宝之旅
既然 get_bloginfo()
频繁地使用 get_option()
函数来从数据库中获取信息,那么咱们就来深入了解一下 get_option()
。
function get_option( string $option, mixed $default = false ): mixed {
global $wpdb;
/**
* Filters the value of an existing option before it is retrieved.
*
* The dynamic portion of the hook name, `$option`, refers to the option name.
*
* @since 2.2.0
*
* @param mixed $pre_option The value to return instead of the option value.
* Default null to bypass this filter.
* @param string $option Option name.
*/
$pre = apply_filters( 'pre_option_' . $option, false, $option );
if ( false !== $pre ) {
return $pre;
}
$alloptions = wp_load_alloptions();
if ( isset( $alloptions[ $option ] ) ) {
$value = $alloptions[ $option ];
} else {
$value = wp_cache_get( $option, 'options' );
if ( false === $value ) {
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
// Has to be get_row rather than get_var because of funkiness with 0, false, null values.
if ( is_object( $row ) ) {
$value = $row->option_value;
} else {
$value = $default;
}
wp_cache_add( $option, $value, 'options' );
}
}
/**
* Filters the value of an option.
*
* The dynamic portion of the hook name, `$option`, refers to the option name.
*
* @since 2.0.0
*
* @param mixed $value Value of the option. If using an object, it will be passed by reference.
* @param string $option Option name.
*/
return apply_filters( 'option_' . $option, $value, $option );
}
-
函数签名:
function get_option( string $option, mixed $default = false ): mixed {
$option
: 这是要获取的选项名。比如,要获取站点名称,就把$option
设置为'blogname'
。$default
: 这是可选参数,用于指定当选项不存在时返回的默认值。默认值是false
。: mixed
:表示此函数返回混合类型的数据。
-
过滤器(Filters):
$pre = apply_filters( 'pre_option_' . $option, false, $option ); if ( false !== $pre ) { return $pre; }
类似于
get_bloginfo()
,get_option()
也使用了过滤器。'pre_option_' . $option
过滤器允许在从数据库中获取选项值之前直接返回一个值,跳过数据库查询。 -
wp_load_alloptions()
:$alloptions = wp_load_alloptions();
wp_load_alloptions()
函数会从数据库的wp_options
表中加载所有自动加载的选项(autoload
字段设置为'yes'
的选项),并将它们存储在一个数组中。这样可以减少数据库查询次数,提高性能。 -
缓存(Cache):
if ( isset( $alloptions[ $option ] ) ) { $value = $alloptions[ $option ]; } else { $value = wp_cache_get( $option, 'options' ); if ( false === $value ) { // ... 从数据库中获取选项值 ... wp_cache_add( $option, $value, 'options' ); } }
get_option()
使用 WordPress 的对象缓存来存储选项值。- 首先,它检查选项是否在
$alloptions
数组中。如果在,就直接从数组中获取选项值。 - 如果不在,就尝试从缓存中获取选项值。
wp_cache_get( $option, 'options' )
函数会从'options'
组中获取$option
的值。 - 如果缓存中也没有,就执行 SQL 查询,从
wp_options
表中获取选项值。 - 最后,将获取到的选项值添加到缓存中,以便下次使用。
- 首先,它检查选项是否在
-
数据库查询:
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) ); if ( is_object( $row ) ) { $value = $row->option_value; } else { $value = $default; }
如果缓存中没有找到选项值,
get_option()
就会执行 SQL 查询来从数据库中获取。$wpdb->prepare()
函数用于预处理 SQL 查询,以防止 SQL 注入攻击。$wpdb->get_row()
函数执行 SQL 查询,并返回结果集的第一行作为一个对象。- 如果查询成功,就从对象中获取
option_value
字段的值。 - 如果查询失败(例如,选项不存在),就返回
$default
参数指定的值。
-
最后的过滤器:
return apply_filters( 'option_' . $option, $value, $option );
在返回选项值之前,
get_option()
还会应用'option_' . $option
过滤器,允许开发者修改最终的选项值。
第四部分:get_blog_version()
:常量里的秘密
get_bloginfo()
在 $show
为 'version'
时,会调用 get_blog_version()
函数来获取 WordPress 的版本号。咱们来看看 get_blog_version()
的源码:
function get_blog_version() {
include ABSPATH . WPINC . '/version.php';
return $wp_version;
}
这段代码非常简单:
-
包含
version.php
:include ABSPATH . WPINC . '/version.php';
它包含了
wp-includes/version.php
文件。这个文件定义了 WordPress 的版本号常量$wp_version
。 -
返回
$wp_version
:return $wp_version;
它直接返回
$wp_version
常量的值。
第五部分:实战演练:用 get_bloginfo()
获取站点信息
好了,理论知识讲了一大堆,现在咱们来做一些实战演练,看看如何使用 get_bloginfo()
函数来获取站点信息。
$show 参数 |
描述 | 示例输出 |
---|---|---|
'name' |
站点名称 | '我的博客' |
'description' |
站点描述 | '分享我的想法和经验' |
'url' |
站点 URL | 'https://example.com' |
'home' |
站点首页 URL | 'https://example.com' |
'admin_email' |
管理员邮箱 | '[email protected]' |
'version' |
WordPress 版本号 | '6.3.1' |
'stylesheet_url' |
主题样式表URL | 'https://example.com/wp-content/themes/my-theme/style.css' |
示例代码:
<?php
$site_name = get_bloginfo( 'name' );
$site_description = get_bloginfo( 'description' );
$site_url = get_bloginfo( 'url' );
$wp_version = get_bloginfo( 'version' );
echo '站点名称:' . $site_name . '<br>';
echo '站点描述:' . $site_description . '<br>';
echo '站点 URL:' . $site_url . '<br>';
echo 'WordPress 版本:' . $wp_version . '<br>';
?>
这段代码会输出站点的名称、描述、URL 和 WordPress 版本号。
第六部分:高级技巧:使用过滤器自定义 get_bloginfo()
的输出
WordPress 的过滤器机制非常强大,可以让你轻松地自定义 get_bloginfo()
的输出结果。
示例:修改站点名称
function my_custom_blogname( $blogname ) {
return '我的超级博客';
}
add_filter( 'option_blogname', 'my_custom_blogname' );
这段代码使用 option_blogname
过滤器来修改站点名称。它定义了一个名为 my_custom_blogname
的函数,该函数接受站点名称作为参数,并返回修改后的站点名称。add_filter()
函数将 my_custom_blogname
函数添加到 option_blogname
过滤器中。
现在,当你调用 get_bloginfo( 'name' )
时,它会返回 '我的超级博客'
,而不是数据库中存储的站点名称。
第七部分:注意事项
- 性能: 尽量避免在循环中调用
get_bloginfo()
,因为它可能会导致多次数据库查询,影响性能。可以将结果缓存起来,然后在循环中使用缓存的值。 - 安全性: 注意对
get_bloginfo()
的输出进行适当的转义,以防止 XSS 攻击。 - 多站点: 在多站点 WordPress 中,
get_bloginfo()
会返回当前站点的相关信息。
总结
get_bloginfo()
函数是 WordPress 中一个非常重要的函数,它可以帮助你轻松地获取站点的各种信息。通过深入了解它的源码,你可以更好地理解 WordPress 的工作原理,并使用过滤器来自定义它的输出结果。希望今天的探险之旅对你有所帮助!下次再见!