各位听众朋友们,大家好!我是今天的主讲人,咱们今天来扒一扒 WordPress 里一个默默无闻但又举足轻重的函数—— add_option()
,看看它到底是怎么跟数据库里的 wp_options
表眉来眼去,以及它背后的缓存机制是怎么运作的。
准备好了吗?咱们这就开始!
add_option()
:初识庐山真面目
add_option()
函数,顾名思义,就是用来添加一个选项(option)到 WordPress 的选项数据库中。这个数据库,实际上就是咱们熟悉的 wp_options
表。这个表就像一个巨大的键值对存储,WordPress 用它来保存各种各样的设置,比如站点标题、URL、主题设置等等。
先来看一下 add_option()
函数的原型:
function add_option( string $name, mixed $value = '', string $deprecated = '', string $autoload = 'yes' ): bool {
global $wpdb, $wp_suspend_cache_addition;
// 省略代码...
}
参数解释:
$name
:选项的名字,必须是唯一的,就像人的名字一样,不能重名。$value
:选项的值,可以是字符串、数字、数组、对象,你想存什么都可以。$deprecated
:已弃用的参数,别管它。$autoload
:是否自动加载。如果设置为'yes'
,WordPress 会在每次加载时自动加载这个选项,提高访问速度。如果设置为'no'
,只有在需要的时候才会加载。
返回值:
true
:成功添加选项。false
:添加失败,通常是因为选项已经存在。
add_option()
的幕后英雄:wp_options
表
wp_options
表是 add_option()
函数的舞台。这个表结构通常如下:
字段名 | 数据类型 | 描述 |
---|---|---|
option_id |
bigint(20) unsigned |
主键,自增长,唯一标识一个选项。 |
option_name |
varchar(191) |
选项的名字,就是咱们在 add_option() 中传入的 $name 参数。 |
option_value |
longtext |
选项的值,就是咱们在 add_option() 中传入的 $value 参数。 |
autoload |
varchar(20) |
是否自动加载,就是咱们在 add_option() 中传入的 $autoload 参数,值为 'yes' 或 'no' 。 |
add_option()
函数的主要任务就是往这张表里插入数据。
源码解读:add_option()
的内部运作
接下来,咱们深入 add_option()
的源码,看看它到底是怎么工作的:
function add_option( string $name, mixed $value = '', string $deprecated = '', string $autoload = 'yes' ): bool {
global $wpdb, $wp_suspend_cache_addition;
// 1. 检查选项名字是否为空
if ( empty( $name ) ) {
return false;
}
// 2. 检查选项是否已经存在
if ( get_option( $name ) !== false ) {
return false;
}
// 3. 序列化选项值
$value = maybe_serialize( $value );
// 4. 执行数据库插入操作
$autoload = ( 'no' === $autoload ) ? 'no' : 'yes';
$result = $wpdb->insert(
$wpdb->options,
array(
'option_name' => $name,
'option_value' => $value,
'autoload' => $autoload,
),
array(
'%s',
'%s',
'%s',
)
);
// 5. 如果插入成功,则将选项添加到缓存中
if ( $result ) {
if ( ! isset( $wp_suspend_cache_addition ) || ! $wp_suspend_cache_addition ) {
wp_cache_add( $name, $value, 'options' );
}
/**
* Fires after an option is successfully added.
*
* @since 2.0.0
*
* @param string $option Name of the option to add.
* @param mixed $value Value of the option.
*/
do_action( 'add_option', $name, $value );
return true;
}
return false;
}
代码分析:
-
参数检查: 首先,函数会检查选项的名字
$name
是否为空。如果为空,直接返回false
,因为没有名字的选项就像没有名字的人一样,是无法存在的。 -
检查选项是否已经存在: 使用
get_option()
函数来检查选项是否已经存在。如果存在,也返回false
,因为同一个名字的选项只能有一个,就像一个人不能有两个身份证号一样。if ( get_option( $name ) !== false ) { return false; }
get_option()
函数的作用是从数据库或缓存中获取选项的值。后面咱们会详细讲解get_option()
函数。 -
序列化选项值: 使用
maybe_serialize()
函数对选项的值$value
进行序列化。这是因为wp_options
表的option_value
字段是longtext
类型,只能存储字符串。如果$value
是数组或对象,就需要先将其序列化成字符串才能存储到数据库中。$value = maybe_serialize( $value );
maybe_serialize()
函数的源码如下:function maybe_serialize( $data ) { if ( is_array( $data ) || is_object( $data ) ) { return serialize( $data ); } if ( is_serialized( $data ) ) { return serialize( $data ); } return $data; }
这个函数会判断
$data
是否是数组或对象,如果是,就使用serialize()
函数将其序列化成字符串。如果$data
已经是序列化的字符串,也会再次序列化,以确保其格式正确。 -
执行数据库插入操作: 使用
$wpdb->insert()
方法将选项插入到wp_options
表中。$autoload = ( 'no' === $autoload ) ? 'no' : 'yes'; $result = $wpdb->insert( $wpdb->options, array( 'option_name' => $name, 'option_value' => $value, 'autoload' => $autoload, ), array( '%s', '%s', '%s', ) );
这里,
$wpdb
是 WordPress 的数据库操作对象,$wpdb->options
表示wp_options
表。$wpdb->insert()
方法接受三个参数:- 表名:
$wpdb->options
- 要插入的数据:一个关联数组,键是字段名,值是要插入的值。
- 数据类型:一个数组,指定每个字段的数据类型。
%s
表示字符串。
- 表名:
-
添加到缓存: 如果数据库插入操作成功,就使用
wp_cache_add()
函数将选项添加到缓存中。if ( $result ) { if ( ! isset( $wp_suspend_cache_addition ) || ! $wp_suspend_cache_addition ) { wp_cache_add( $name, $value, 'options' ); } // ... }
wp_cache_add()
函数用于将数据添加到 WordPress 的对象缓存中。对象缓存是一种内存缓存机制,可以显著提高 WordPress 的性能。wp_cache_add()
函数接受三个参数:$key
:缓存的键,这里是选项的名字$name
。$data
:要缓存的数据,这里是选项的值$value
。$group
:缓存组,这里是'options'
。
$wp_suspend_cache_addition
是一个全局变量,用于临时禁用缓存添加操作。 -
触发 Action Hook: 成功添加选项后,会触发一个 Action Hook
add_option
,允许其他插件或主题执行自定义操作。do_action( 'add_option', $name, $value );
Action Hook 是 WordPress 提供的一种扩展机制,允许开发者在特定的事件发生时执行自定义代码。
-
返回结果: 最后,函数返回
true
表示添加成功,否则返回false
。
缓存机制:加速访问,提升性能
add_option()
函数的源码中,咱们看到了 wp_cache_add()
函数。这个函数是 WordPress 缓存机制的关键。为了理解 add_option()
函数的缓存机制,咱们需要了解以下几个概念:
- 对象缓存(Object Cache): WordPress 的对象缓存是一种内存缓存机制,用于缓存数据库查询结果和其他计算密集型操作的结果。它可以显著提高 WordPress 的性能,减少数据库的负载。
- 缓存组(Cache Group): 对象缓存可以分为多个缓存组,每个缓存组用于存储特定类型的数据。
add_option()
函数使用的缓存组是'options'
,用于存储选项数据。 - 缓存键(Cache Key): 每个缓存项都有一个唯一的键,用于标识该缓存项。
add_option()
函数使用的缓存键是选项的名字$name
。
add_option()
函数的缓存机制如下:
- 当使用
add_option()
函数添加一个选项时,如果数据库插入操作成功,该选项会被添加到对象缓存的'options'
缓存组中,缓存键为选项的名字。 - 当使用
get_option()
函数获取一个选项时,WordPress 会首先从对象缓存中查找该选项。如果找到,就直接返回缓存中的值,而无需查询数据库。 - 如果对象缓存中没有找到该选项,WordPress 才会查询数据库,并将查询结果添加到对象缓存中,以便下次访问时可以直接从缓存中获取。
这种缓存机制可以显著提高 WordPress 的性能,因为从内存中读取数据比从数据库中读取数据要快得多。
get_option()
:选项读取的利器
既然提到了缓存,就不得不说一下 get_option()
函数,它是 add_option()
的好搭档,负责从数据库或缓存中获取选项的值。
function get_option( string $option, mixed $default = false ) {
global $wpdb;
// 1. 尝试从缓存中获取选项
$value = wp_cache_get( $option, 'options' );
// 2. 如果缓存中没有找到,则从数据库中获取
if ( false === $value ) {
$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
// 3. 如果数据库中没有找到,则返回默认值
if ( is_null( $row ) ) {
return $default;
}
// 4. 反序列化选项值
$value = $row->option_value;
$value = maybe_unserialize( $value );
// 5. 将选项添加到缓存中
wp_cache_add( $option, $value, 'options' );
}
/**
* Filters the value of an existing option.
*
* The dynamic portion of the hook name, `$option`, refers to the option name.
*
* @since 2.2.0
*
* @param mixed $value Value of the option.
*/
return apply_filters( "option_{$option}", $value );
}
代码分析:
-
尝试从缓存中获取: 首先,
get_option()
函数会尝试从对象缓存的'options'
缓存组中获取选项的值。如果找到了,就直接返回缓存中的值。$value = wp_cache_get( $option, 'options' );
wp_cache_get()
函数用于从 WordPress 的对象缓存中获取数据。它接受两个参数:$key
:缓存的键,这里是选项的名字$option
。$group
:缓存组,这里是'options'
。
-
从数据库中获取: 如果缓存中没有找到该选项,
get_option()
函数会查询数据库,从wp_options
表中获取选项的值。if ( false === $value ) { $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) ); // ... }
这里,
$wpdb->get_row()
方法用于执行数据库查询,并返回结果的第一行。$wpdb->prepare()
方法用于防止 SQL 注入攻击。 -
返回默认值: 如果在数据库中也没有找到该选项,
get_option()
函数会返回默认值$default
。 -
反序列化选项值: 如果从数据库中找到了该选项,
get_option()
函数会使用maybe_unserialize()
函数对选项的值进行反序列化。这是因为wp_options
表的option_value
字段存储的是序列化后的字符串。$value = $row->option_value; $value = maybe_unserialize( $value );
maybe_unserialize()
函数的源码如下:function maybe_unserialize( $original ) { if ( is_serialized( $original ) ) { // don't attempt to unserialize data that wasn't serialized going in return @unserialize( $original ); } return $original; }
这个函数会判断
$original
是否是序列化的字符串,如果是,就使用unserialize()
函数将其反序列化成数组或对象。 -
添加到缓存: 从数据库中获取选项的值后,
get_option()
函数会将该选项添加到对象缓存中,以便下次访问时可以直接从缓存中获取。wp_cache_add( $option, $value, 'options' );
-
应用 Filter Hook: 最后,
get_option()
函数会应用一个 Filter Hookoption_{$option}
,允许其他插件或主题修改选项的值。return apply_filters( "option_{$option}", $value );
Filter Hook 是 WordPress 提供的一种扩展机制,允许开发者在特定的事件发生时修改数据。
update_option()
:修改选项,与时俱进
除了添加和获取选项,WordPress 还提供了 update_option()
函数,用于修改已存在的选项。
function update_option( string $option, mixed $value, string|null $autoload = null ): bool {
global $wpdb, $wp_suspend_cache_invalidation;
// 1. 序列化选项值
$value = maybe_serialize( $value );
// 2. 查询选项是否已经存在
$old_value = get_option( $option );
// 3. 如果选项已经存在,则更新数据库
if ( false !== $old_value ) {
// ...
} else {
// 4. 如果选项不存在,则添加选项
return add_option( $option, $value, '', $autoload );
}
// 省略代码...
}
update_option()
函数会首先序列化选项值,然后查询选项是否已经存在。如果选项已经存在,则更新数据库中的选项值,并更新缓存。如果选项不存在,则调用 add_option()
函数添加选项。
delete_option()
:删除选项,挥手告别
最后,咱们再来看看 delete_option()
函数,用于删除一个选项。
function delete_option( string $option ): bool {
global $wpdb;
// 1. 从数据库中删除选项
$result = $wpdb->delete( $wpdb->options, array( 'option_name' => $option ) );
// 2. 从缓存中删除选项
if ( $result ) {
wp_cache_delete( $option, 'options' );
/**
* Fires after an option is successfully deleted.
*
* @since 2.0.0
*
* @param string $option Name of the option to delete.
*/
do_action( 'delete_option', $option );
return true;
}
return false;
}
delete_option()
函数会首先从数据库中删除选项,然后从缓存中删除选项。
总结:add_option()
、get_option()
、update_option()
、delete_option()
的协作
add_option()
、get_option()
、update_option()
和 delete_option()
这四个函数是 WordPress 中选项管理的核心函数。它们共同协作,实现了选项的添加、获取、修改和删除操作。
add_option()
:添加一个选项到wp_options
表,并将选项添加到缓存中。get_option()
:从缓存或数据库中获取选项的值。update_option()
:修改wp_options
表中的选项值,并更新缓存。如果选项不存在,则添加选项。delete_option()
:从wp_options
表中删除选项,并从缓存中删除选项。
这四个函数的协作,保证了 WordPress 选项数据的持久化存储和高效访问。
好了,今天的讲座就到这里。希望大家对 add_option()
函数以及相关的选项管理机制有了更深入的了解。记住,理解这些底层机制,才能更好地开发 WordPress 插件和主题,打造更加强大的 WordPress 站点!感谢大家的收听!