WordPress函数:add_option 添加设置选项
编辑文章简介
add_option 函数用于在WordPress选项表中创建并存储一个新的设置项,常用于保存插件、主题的配置信息。它是WordPress持久化存储简单数据(如开关状态、文本参数)最核心的工具之一。
语法
add_option( string $option, mixed $value = '', string $deprecated = '', string|bool $autoload = 'yes' )
核心文件: wp-includes/option.php。该函数内部会调用 wp_protect_special_option 进行关键选项名检查,并最终通过 $wpdb 类执行SQL INSERT 操作。
参数与返回值说明:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
$option |
字符串 | (必填) | 要创建的选项名称。建议使用小写字母、数字和下划线,并确保唯一性。 |
$value |
混合 | '' |
要存储的选项值。可以是字符串、数组、数字、对象(需可序列化)。 |
$deprecated |
字符串 | '' |
已弃用。历史上用于描述,现已不再使用,传递任何值均无效。 |
$autoload |
字符串/布尔 | 'yes' |
是否在WordPress所有页面加载时自动从数据库载入该选项。设为 'no' 可提升性能,适用于不常用的后台选项。 |
| 返回值 | 布尔 | 成功添加返回 true。若选项已存在,则返回 false。 |
用法
基础用法
在插件或主题的初始化函数中,存储一个简单的设置值。这是最常见的场景,例如设置一个首次安装的标记。
// 在插件主文件或主题的 functions.php 中添加
function myplugin_setup_default_options() {
// 如果选项 'myplugin_first_install' 不存在,则创建它
if ( false === get_option( 'myplugin_first_install' ) ) {
add_option( 'myplugin_first_install', date( 'Y-m-d H:i:s' ) );
}
}
// 在适当的钩子上运行,例如插件激活时或 `init` 动作
add_action( 'init', 'myplugin_setup_default_options' );
为什么先检查 get_option? 因为 add_option 在选项已存在时会直接返回 false 且不修改原值。这种“只添加一次”的逻辑确保了默认设置不会被意外覆盖。
进阶用法
存储结构化数据(如数组)并管理自动加载行为,适用于包含多个子项的复杂配置。
// 存储一个包含多个设置的关联数组,并禁止自动加载
function mytheme_save_complex_settings() {
$complex_settings = array(
'layout' => 'sidebar-right',
'custom_css' => 'body { color: #333; }',
'featured_enabled' => true,
'api_key' => '', // 用户稍后填写
);
// 注意:我们传递了 $autoload='no',因为该配置可能只在后台设置页面使用
add_option( 'mytheme_design_config', $complex_settings, '', 'no' );
}
// 假设在主题切换时运行此函数
add_action( 'after_switch_theme', 'mytheme_save_complex_settings' );
// 如何读取这个选项?使用 get_option,它自动反序列化数组。
$settings = get_option( 'mytheme_design_config' );
if ( $settings && isset( $settings['layout'] ) ) {
// 在模板中使用时,务必对输出进行转义
echo '布局模式:' . esc_html( $settings['layout'] );
}
易错点
- 覆盖已有选项
直接调用add_option( 'existing_option', 'new_value' )不会更新已存在的选项。若需“添加或更新”,应使用update_option函数。add_option应仅在初始化默认值时使用。 -
存储非标量数据时的序列化陷阱
add_option会自动对数组、对象等非标量数据进行序列化后存储。但如果你存储一个已序列化的字符串,它会被再次序列化,导致取出时得到混乱的数据。确保$value参数总是传递原始数据结构,而非序列化后的字符串。 -
选项名冲突
使用过于通用的选项名(如version,settings)极易与其他插件或主题冲突。始终为选项名添加唯一前缀,例如myplugin_或mytheme_。 -
忽视自动加载对性能的影响
将所有选项的$autoload都设为'yes'(默认),会导致wp_load_alloptions()函数一次性加载大量不常用的数据到内存,拖慢每个页面。请仅为高频使用的核心选项开启自动加载。 -
未考虑多站点环境
在WordPress多站点(Multisite)网络中,add_option操作的是当前站点的选项表(如wp_2_options)。如果需要添加网络级别的选项,应使用add_site_option函数。
最佳实践
性能优化:精确控制自动加载
将选项分为“高频”与“低频”使用两类。首页、文章页等几乎每个页面都需要的核心设置(如主题名称、基础开关)可设为自动加载。而仅在后台上某个设置页面使用的详细配置,应设为 autoload='no'。
// 高频选项:自动加载
add_option( 'myplugin_core_feature_enabled', true, '', 'yes' );
// 低频选项:不自动加载
add_option( 'myplugin_debug_log_history', array(), '', 'no' );
代码可维护性:集中管理选项名
在大型项目中,分散在各处的选项名字符串是“魔法数字”的一种,难以维护和查找。定义一个类或常量来集中管理所有选项名。
// 在插件的主类或专用配置文件中定义
class MyPlugin_Config {
const OPTION_INSTALL_DATE = 'myplugin_install_date';
const OPTION_USER_SETTINGS = 'myplugin_user_settings';
const OPTION_ADVANCED_FLAGS = 'myplugin_advanced_flags';
}
// 使用时
add_option( MyPlugin_Config::OPTION_INSTALL_DATE, current_time( 'mysql' ) );
$settings = get_option( MyPlugin_Config::OPTION_USER_SETTINGS );
安全性增强:处理用户输入
虽然 add_option 本身会将值安全地存入数据库,但如果存储的值来源于用户输入(如表单提交),必须在存储前进行严格的验证和清理,以防止存储恶意代码。并且在输出时必须再次转义。
// 假设接收来自表单的输入
$user_input_text = $_POST['custom_message'] ?? ''; // 不安全!
// 在存储前进行清理(根据数据类型选择合适的函数)
$clean_value = sanitize_textarea_field( $user_input_text ); // 清理文本区域内容
// 现在可以安全地存储
update_option( 'myplugin_user_message', $clean_value ); // 此处用update_option,因为可能已存在
// --- 在模板中输出时 ---
$stored_message = get_option( 'myplugin_user_message' );
// 必须根据输出上下文进行转义
echo '<p>' . esc_textarea( $stored_message ) . '</p>'; // 如果回填到textarea
// 或
echo '<div>' . wp_kses_post( $stored_message ) . '</div>'; // 如果允许少量HTML
与现代开发模式结合:为REST API准备
如果你在开发支持WordPress REST API的主题或插件,可以考虑将选项通过 register_rest_route 暴露为API端点。此时,使用 get_option 读取并通过API返回时,应确保数据结构清晰(如JSON友好),并考虑权限检查(permission_callback)。
add_action( 'rest_api_init', function () {
register_rest_route( 'myplugin/v1', '/settings', array(
'methods' => 'GET',
'callback' => function () {
// 获取所有相关选项,组装成一个对象
$data = array(
'design' => get_option( 'myplugin_design_config', array() ),
'flags' => get_option( 'myplugin_feature_flags', array() ),
);
// 直接返回,WP REST API会自动处理JSON序列化
return $data;
},
'permission_callback' => function () {
// 重要:进行权限检查,例如只允许管理员访问
return current_user_can( 'manage_options' );
}
) );
} );