各位程序猿、攻城狮、代码艺术家们,大家好!我是老码农,今天咱们来扒一扒 WordPress 里一对儿看似相像,实则有点小脾气的函数:get_site_option()
和 get_option()
。
开场白:话说江湖事,选项也分家
在 WordPress 的世界里,选项就像江湖里的秘籍,记录着各种门派的独门绝技——插件设置、主题风格等等。get_option()
就像是每个门派自己保管的秘籍副本,而 get_site_option()
则像是武林盟主手里那份总纲,记录着整个武林的规则。
在单站点模式下,get_option()
就可以打遍天下无敌手,但在多站点模式下,get_site_option()
就显得尤为重要了。 接下来,我们就深入源代码,看看它们到底有啥不同。
第一幕:get_option()
的独角戏
首先,让我们回顾一下 get_option()
。 这个函数的作用是根据给定的选项名($option
),从 WordPress 的 wp_options
表中获取对应的选项值。 如果找到了,就返回选项值;如果没找到,就返回一个默认值(通常是 false
)。
咱们看看 get_option()
的简化版代码(为了便于理解,我省略了一些细节):
function get_option( $option, $default = false ) {
global $wpdb;
static $notoptions;
if ( isset( $notoptions[ $option ] ) ) {
return $default;
}
$alloptions = wp_load_alloptions(); // 加载所有自动加载的选项
if ( isset( $alloptions[ $option ] ) ) {
return apply_filters( 'pre_option_' . $option, $alloptions[ $option ] );
}
$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;
$value = maybe_unserialize( $value );
$value = apply_filters( 'pre_option_' . $option, $value );
return $value;
} else {
$notoptions[ $option ] = true;
return apply_filters( 'pre_option_' . $option, $default );
}
}
这段代码的核心逻辑是:
- 缓存检查: 先看静态变量
$notoptions
里有没有记录过这个选项,如果有,说明之前没找到过,直接返回默认值。 - 自动加载选项检查: 检查
$alloptions
数组 (由wp_load_alloptions()
函数加载) 中是否已经存在该选项。如果存在,直接返回。wp_load_alloptions()
从数据库读取所有autoload
为yes
的选项,存入缓存。 - 数据库查询: 如果缓存里没有,就直接去
wp_options
表里查,查到了就反序列化,然后返回;没查到就在$notoptions
里记一笔,下次就不用查了,直接返回默认值。
第二幕:get_site_option()
的登场
现在,主角 get_site_option()
闪亮登场了。 在多站点模式下,每个站点都有自己的 wp_options
表,而 get_site_option()
则是用来获取整个网络(network)级别的选项的。
get_site_option()
的代码看起来有点复杂,但核心思路其实很简单:
function get_site_option( $option, $default = false ) {
global $wpdb, $wp_current_db_version;
static $sitedata = array();
if ( isset( $sitedata[ $option ] ) ) {
return $sitedata[ $option ];
}
$network_id = get_current_site()->id;
$key = $option . '_' . $network_id;
$value = wp_cache_get( $key, 'site-options' );
if ( false !== $value ) {
$sitedata[ $option ] = $value;
return $value;
}
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->sitemeta WHERE site_id = %d AND meta_key = %s", $network_id, $option ) );
if ( is_object( $row ) ) {
$value = $row->option_value;
$value = maybe_unserialize( $value );
} else {
$value = get_network_option(null, $option, $default); //Fallback到get_network_option
if($value === $default){
$value = $default;
}
}
wp_cache_set( $key, $value, 'site-options' );
$sitedata[ $option ] = $value;
return $value;
}
我们来分解一下:
- 静态缓存: 同样,先检查静态变量
$sitedata
里有没有缓存,有就直接返回。 - 缓存键构建: 构建缓存键,将选项名和当前站点的网络 ID 组合起来,确保缓存的唯一性。
- WP Cache 检查: 使用 WordPress 的对象缓存(WP Cache)来检查是否有缓存,有就直接返回。 WP Cache 是一个强大的缓存系统,可以显著提高性能。
- 数据库查询: 如果缓存里没有,就去
wp_sitemeta
表里查,这个表专门存储网络级别的选项。 注意,这里用到了site_id
,也就是网络 ID。 - 反序列化: 查到了就反序列化。
- Fallback到get_network_option: 如果在
wp_sitemeta
表中没有找到,则 fallback 到get_network_option
。get_network_option
允许指定网络ID,如果没有指定,则使用当前网络ID。 这允许从特定的网络或主网络获取选项。 - 缓存设置: 最后,把查到的结果放进 WP Cache 和静态变量
$sitedata
里,方便下次使用。
第三幕:多站点模式下的恩怨情仇
现在,我们来总结一下 get_option()
和 get_site_option()
在多站点模式下的区别:
特性 | get_option() |
get_site_option() |
---|---|---|
存储位置 | 每个站点的 wp_options 表 |
wp_sitemeta 表 (存储网络级别的选项) |
作用域 | 单个站点 | 整个网络(所有站点共享) |
使用场景 | 获取特定站点的设置,比如主题设置、插件设置等 | 获取整个网络的设置,比如网络管理员邮箱、注册设置等 |
数据表 | wp_options |
wp_sitemeta |
举个例子:
- 假设你想获取每个站点的主题颜色设置,你应该用
get_option( 'theme_color' )
。 - 假设你想获取整个网络的注册设置,比如是否允许用户注册,你应该用
get_site_option( 'registration' )
。
第四幕:代码实战
为了更好地理解,我们来写几个简单的例子:
例子 1:获取当前站点的主题颜色
$theme_color = get_option( 'theme_color', '#ffffff' ); // 默认白色
echo '当前站点的主题颜色是:' . $theme_color;
例子 2:获取网络管理员邮箱
$admin_email = get_site_option( 'admin_email' );
echo '网络管理员邮箱是:' . $admin_email;
例子 3:设置和获取站点选项
// 设置站点选项
update_option( 'my_custom_option', 'Hello World!' );
// 获取站点选项
$my_option = get_option( 'my_custom_option' );
echo '我的站点选项是:' . $my_option;
例子 4:设置和获取网络选项
// 设置网络选项
update_site_option( 'my_custom_site_option', 'Hello Network!' );
// 获取网络选项
$my_site_option = get_site_option( 'my_custom_site_option' );
echo '我的网络选项是:' . $my_site_option;
第五幕:update_option()
和 update_site_option()
的配合
既然说了 get_option()
和 get_site_option()
,就不得不提一下它们的好基友:update_option()
和 update_site_option()
。
update_option( $option, $value )
:用于更新单个站点的选项。update_site_option( $option, $value )
:用于更新整个网络的选项。
它们的代码逻辑也和 get_option()
和 get_site_option()
类似,我就不一一展开了,大家可以自己去研究一下。
第六幕:总结陈词
好了,今天的讲座就到这里。 咱们深入剖析了 get_site_option()
和 get_option()
的源码,了解了它们在多站点模式下的区别和使用场景。
简单来说:
get_option()
负责管理单个站点的选项,存储在wp_options
表里。get_site_option()
负责管理整个网络的选项,存储在wp_sitemeta
表里。
记住,在多站点模式下,一定要根据选项的作用域选择正确的函数,否则可能会出现意想不到的问题。
希望今天的讲解对大家有所帮助。 记住,代码的世界是充满乐趣的,只要你肯钻研,就能发现更多的奥秘。 下次再见!