阐述 `add_option()` 和 `delete_option()` 函数的源码,并与 `update_option()` 进行对比。

各位观众老爷,早上好!我是你们的老朋友,今天咱们不聊八卦,只谈技术,而且是WordPress技术,具体来说,就是add_option(), delete_option()update_option()这三兄弟的源码分析。别害怕,源码嘛,就像一堆乐高积木,拆开了看,其实也没那么可怕。咱们争取用最通俗易懂的方式,把它们扒个精光。

开场白:Option 的江湖地位

在WordPress的世界里,Option就像是网站的记忆细胞,存储着各种配置信息,比如网站标题、描述、主题设置、插件配置等等。想象一下,如果没有Option,每次打开网站,都得重新设置一遍,那还不如用记事本写静态页面呢!

add_option(), delete_option()update_option() 这三个函数,就是负责Option的增删改查操作的三剑客。掌握了它们,你就能轻松玩转WordPress的配置系统,让你的网站更加个性化、更加强大。

第一部分:add_option() – 初出茅庐的 Option

add_option() 函数的作用是向 WordPress 数据库中添加一个新的 option。如果 option 已经存在,函数会直接返回 false,而不会覆盖已有的值。我们先来看看它的源码(简化版,去掉了部分安全检查和兼容性处理):

function add_option( string $name, mixed $value = '', string $deprecated = '', string|bool $autoload = 'yes' ): bool {
    global $wpdb;

    // 1. 检查 option 名是否合法 (略)

    // 2. 序列化 value (重要!)
    $value = maybe_serialize( $value );

    // 3. 构建 SQL 语句
    $sql = $wpdb->prepare(
        "INSERT INTO {$wpdb->options} (option_name, option_value, autoload) VALUES (%s, %s, %s)",
        $name,
        $value,
        $autoload
    );

    // 4. 执行 SQL 语句
    try {
        $result = $wpdb->query( $sql );
    } catch (Exception $e) {
        $result = false;
    }

    // 5. 清除缓存 (重要!)
    wp_cache_delete( $name, 'options' );

    // 6. 返回结果
    return (bool) $result;
}

咱们来逐行解读一下:

  1. global $wpdb;: 这句代码引入了 WordPress 的数据库操作对象 $wpdb,所有数据库操作都得靠它。 $wpdb就像是你的数据库管理员,你想干啥都得跟他打招呼。
  2. $value = maybe_serialize( $value );: 这个是关键!WordPress 的 Option 可以存储各种类型的数据,比如字符串、数字、数组、对象等等。但是,数据库只能存储字符串啊!所以,我们需要把这些复杂的数据结构序列化成字符串,才能存进数据库。maybe_serialize() 函数就是负责干这个的,它会判断 $value 是否需要序列化,如果已经是字符串了,就直接返回,否则就进行序列化。
  3. $sql = $wpdb->prepare(...): 构建 SQL 语句,准备插入数据。$wpdb->prepare() 函数可以防止 SQL 注入攻击,它会将 SQL 语句中的变量进行转义,确保安全。
  4. $result = $wpdb->query( $sql );: 执行 SQL 语句,将数据插入到 wp_options 表中。
  5. wp_cache_delete( $name, 'options' );: 清除缓存。WordPress 会对 Option 进行缓存,以提高性能。但是,当我们添加或修改了 Option 后,需要清除缓存,才能确保下次读取的是最新的数据。
  6. return (bool) $result;: 返回操作结果,true 表示添加成功,false 表示添加失败。

add_option() 的参数说明:

参数 类型 描述
$name string Option 的名称,必须是唯一的。就像每个人的名字一样,不能重名。
$value mixed Option 的值,可以是任何类型的数据,比如字符串、数字、数组、对象等等。
$deprecated string 已废弃的参数,不要使用。
$autoload string | bool 是否自动加载。如果设置为 'yes',WordPress 会在每次加载时自动加载该 Option,提高访问速度。如果设置为 'no',则需要手动加载。如果设置为 true或者false,效果相同。一般来说,常用的 Option 设置为 'yes',不常用的设置为 'no'

举个栗子:

// 添加一个名为 'my_plugin_version' 的 option,值为 '1.0.0',自动加载
add_option( 'my_plugin_version', '1.0.0', '', 'yes' );

// 添加一个名为 'my_plugin_settings' 的 option,值为一个数组,不自动加载
$settings = array(
    'option1' => 'value1',
    'option2' => 'value2',
);
add_option( 'my_plugin_settings', $settings, '', 'no' );

注意事项:

  • Option 的名称应该具有描述性,方便理解。
  • 避免使用过长的 Option 名称,影响性能。
  • 谨慎设置 $autoload 参数,避免加载过多的 Option,影响网站速度。
  • add_option()只能新增,不能修改,如果想修改,请使用update_option()

第二部分:delete_option() – 挥一挥衣袖,不带走一片云彩

delete_option() 函数的作用是从 WordPress 数据库中删除一个 option。

function delete_option( string $name ): bool {
    global $wpdb;

    // 1. 检查 option 名是否合法 (略)

    // 2. 构建 SQL 语句
    $sql = $wpdb->prepare(
        "DELETE FROM {$wpdb->options} WHERE option_name = %s",
        $name
    );

    // 3. 执行 SQL 语句
    $result = $wpdb->query( $sql );

    // 4. 清除缓存 (重要!)
    wp_cache_delete( $name, 'options' );

    // 5. 返回结果
    return (bool) $result;
}

这个函数相对简单,咱们也来简单解读一下:

  1. global $wpdb;: 同样引入了数据库操作对象。
  2. $sql = $wpdb->prepare(...): 构建 SQL 语句,准备删除数据。
  3. $result = $wpdb->query( $sql );: 执行 SQL 语句,从 wp_options 表中删除数据。
  4. wp_cache_delete( $name, 'options' );: 清除缓存,确保下次读取时,该 Option 不存在。
  5. return (bool) $result;: 返回操作结果,true 表示删除成功,false 表示删除失败。

delete_option() 的参数说明:

参数 类型 描述
$name string 要删除的 Option 的名称。

举个栗子:

// 删除名为 'my_plugin_version' 的 option
delete_option( 'my_plugin_version' );

注意事项:

  • 删除 Option 是一个不可逆的操作,请谨慎操作。
  • 删除一个不存在的 Option 不会报错,delete_option() 函数会返回 false

第三部分:update_option() – 旧貌换新颜

update_option() 函数的作用是更新 WordPress 数据库中一个已存在的 option 的值。如果 option 不存在,函数会自动添加一个新的 option。

function update_option( string $name, mixed $value, string|bool $autoload = null ): bool {
    global $wpdb;

    // 1. 检查 option 名是否合法 (略)

    // 2. 序列化 value (重要!)
    $value = maybe_serialize( $value );

    // 3. 检查 option 是否已经存在
    $old_value = get_option( $name );

    // 4. 如果 option 已经存在,则更新它
    if ( false !== $old_value ) {
        // 序列化旧值,用于比较
        $old_value = maybe_serialize( $old_value );

        // 如果新旧值相同,则直接返回 false,不进行更新
        if ( $old_value === $value ) {
            return false;
        }

        // 构建 SQL 语句
        $sql = $wpdb->prepare(
            "UPDATE {$wpdb->options} SET option_value = %s WHERE option_name = %s",
            $value,
            $name
        );

        // 执行 SQL 语句
        $result = $wpdb->query( $sql );

        // 5. 如果 option 不存在,则添加它
    } else {
        $result = add_option( $name, $value, '', $autoload );
    }

    // 6. 如果设置了 autoload 参数,则更新 autoload 字段
    if ( null !== $autoload ) {
        $autoload = ( 'no' === $autoload || false === $autoload ) ? 'no' : 'yes';

        $sql = $wpdb->prepare(
            "UPDATE {$wpdb->options} SET autoload = %s WHERE option_name = %s",
            $autoload,
            $name
        );
        $wpdb->query( $sql );
    }

    // 7. 清除缓存 (重要!)
    wp_cache_delete( $name, 'options' );

    // 8. 返回结果
    return (bool) $result;
}

这个函数稍微复杂一些,咱们来仔细解读一下:

  1. global $wpdb;: 引入数据库操作对象。
  2. $value = maybe_serialize( $value );: 序列化 value。
  3. $old_value = get_option( $name );: 获取 option 的旧值。get_option() 函数用于获取 option 的值,如果 option 不存在,则返回 false
  4. if ( false !== $old_value ) { ... }: 判断 option 是否已经存在。
    • 如果 option 已经存在,则更新它。
    • 先比较新旧值是否相同,如果相同,则直接返回 false,不进行更新,避免不必要的数据库操作。
    • 构建 SQL 语句,准备更新数据。
    • 执行 SQL 语句,更新 wp_options 表中的数据。
  5. else { ... }: 如果 option 不存在,则添加它。直接调用 add_option() 函数。
  6. if ( null !== $autoload ) { ... }: 如果设置了 $autoload 参数,则更新 autoload 字段。
  7. wp_cache_delete( $name, 'options' );: 清除缓存。
  8. return (bool) $result;: 返回操作结果。

update_option() 的参数说明:

参数 类型 描述
$name string Option 的名称。
$value mixed Option 的值。
$autoload string | bool | null 是否自动加载。如果设置为 'yes',WordPress 会在每次加载时自动加载该 Option。如果设置为 'no',则需要手动加载。如果设置为 null,则不更新 autoload 字段,保持原来的值。如果设置为 true或者false,效果相同。

举个栗子:

// 更新名为 'my_plugin_version' 的 option,值为 '1.1.0'
update_option( 'my_plugin_version', '1.1.0' );

// 更新名为 'my_plugin_settings' 的 option,值为一个新的数组,并设置不自动加载
$settings = array(
    'option1' => 'new_value1',
    'option3' => 'value3',
);
update_option( 'my_plugin_settings', $settings, 'no' );

//更新一个不存在的option
update_option( 'new_option', 'new value');

注意事项:

  • update_option() 可以更新已存在的 Option,也可以添加新的 Option。
  • 如果更新的 Option 的值与原来的值相同,update_option() 函数会直接返回 false,不会进行数据库操作。
  • 可以只更新 Option 的值,而不更新 autoload 字段。
  • update_option$autoload 参数为 null 的时候,如果这个option不存在,那么新增的option的autoload为yes.

第四部分:三剑客的对比总结

为了方便大家理解,咱们用一个表格来对比一下这三兄弟:

函数 功能 Option 存在时 Option 不存在时 $autoload 参数 返回值
add_option() 添加一个新的 Option 返回 false,不添加 添加一个新的 Option 'yes''no',指定是否自动加载 true 表示添加成功,false 表示添加失败。
delete_option() 删除一个 Option 删除 Option 返回 false,不报错 无效 true 表示删除成功,false 表示删除失败。
update_option() 更新一个 Option 的值 更新 Option 的值,如果新旧值相同则返回 false 添加一个新的 Option 'yes''no',更新 autoload 字段; null,不更新 autoload 字段; 如果 option 不存在,则新增option,autoload为yes true 表示更新或添加成功,false 表示更新失败(通常是新旧值相同)。

第五部分:实战演练

咱们来做一个简单的插件,演示一下这三兄弟的用法。

<?php
/**
 * Plugin Name: Option 演示插件
 * Description: 演示 add_option, delete_option, update_option 的用法
 * Version: 1.0.0
 */

// 在插件激活时添加一个 option
register_activation_hook( __FILE__, 'option_demo_activate' );
function option_demo_activate() {
    add_option( 'option_demo_version', '1.0.0', '', 'yes' );
}

// 在插件停用时删除 option
register_deactivation_hook( __FILE__, 'option_demo_deactivate' );
function option_demo_deactivate() {
    delete_option( 'option_demo_version' );
}

// 创建一个管理页面,用于修改 option
add_action( 'admin_menu', 'option_demo_admin_menu' );
function option_demo_admin_menu() {
    add_options_page(
        'Option 演示',
        'Option 演示',
        'manage_options',
        'option-demo',
        'option_demo_admin_page'
    );
}

function option_demo_admin_page() {
    // 获取 option 的值
    $version = get_option( 'option_demo_version' );

    // 处理表单提交
    if ( isset( $_POST['submit'] ) ) {
        $new_version = sanitize_text_field( $_POST['version'] );
        update_option( 'option_demo_version', $new_version );
        $version = $new_version;
        echo '<div class="updated"><p>设置已保存!</p></div>';
    }

    ?>
    <div class="wrap">
        <h1>Option 演示</h1>
        <form method="post">
            <label for="version">版本号:</label>
            <input type="text" name="version" id="version" value="<?php echo esc_attr( $version ); ?>"><br><br>
            <input type="submit" name="submit" class="button button-primary" value="保存">
        </form>
    </div>
    <?php
}

这个插件的功能很简单:

  1. 在插件激活时,添加一个名为 option_demo_version 的 Option,值为 1.0.0
  2. 在插件停用时,删除这个 Option。
  3. 创建一个管理页面,允许管理员修改这个 Option 的值。

通过这个插件,你可以更直观地理解 add_option(), delete_option()update_option() 的用法。

第六部分:总结与展望

今天咱们深入探讨了 WordPress 中 add_option(), delete_option()update_option() 这三个重要的函数。它们是 WordPress 配置系统的基石,掌握了它们,你就能更好地控制你的网站,实现各种个性化需求。

当然,Option 只是 WordPress 庞大体系中的一小部分。还有很多其他的 API 和技术等待着我们去探索。希望今天的分享能帮助大家更好地理解 WordPress,也希望大家在未来的学习和工作中,能够灵活运用这些知识,创造出更加精彩的 WordPress 作品!

希望大家多多点赞,多多支持!下次有机会,咱们再聊聊 WordPress 的其他有趣话题。 谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注