WordPress开发笔记

WordPress创建自定义队列数据表与日志数据表示例代码,附字段增改查函数

本文WordPress创建自定义队列数据表与日志数据表代码仅供参考,你可以根据自己的需求修改或使用。

创建数据表代码

//预定义常量
define('ZZW_TABLE_NAME', 'zzw_static_queue'); //数据库队列数据表
define('ZZW_TABLE_LOG_NAME', 'zzw_static_log');//日志数据表

//创建队列数据表与日志数据表
function zzw_create_table() {
    global $wpdb;

    //返回:字符串数据库字符整理,详见:https://developer.wordpress.org/reference/classes/wpdb/get_charset_collate/
    $charset_collate = $wpdb->get_charset_collate();

    // 队列数据表
    $table_name = $wpdb->prefix . ZZW_TABLE_NAME; 
    $sql_queue = "CREATE TABLE $table_name (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        type varchar(20) NOT NULL,
        tax_pt varchar(20) NOT NULL,
        object_id bigint(20) NOT NULL DEFAULT '0',
        status varchar(20) NOT NULL DEFAULT 'pending',
        created datetime NOT NULL,
        updated datetime NOT NULL,
        PRIMARY KEY (id),
        KEY type_status (type, status)
    ) $charset_collate;";
    

    // 日志表
    $table_log_name = $wpdb->prefix . ZZW_TABLE_LOG_NAME;
    $sql_log = "CREATE TABLE $table_log_name (
        log_id bigint(20) NOT NULL AUTO_INCREMENT,
        log_name varchar(20) NOT NULL,
        log_value longtext NOT NULL,
        log_created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (log_id),
        KEY log_name_idx (log_name)
    ) $charset_collate;";
    
    //引入 WordPress 核心文件 upgrade.php,该文件定义了数据库表操作的关键函数 dbDelta()
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
    
    // 执行创建并捕获错误
    $queue_result = dbDelta($sql_queue);
    $log_result = dbDelta($sql_log);
    
    // 增强错误诊断:根据自己需求增删改
    // if (false === $log_result) {
    //     error_log("日志表创建失败: " . $wpdb->last_error);
    //     error_log("执行的SQL: " . $sql_log);
    // } else {
    //     error_log("日志表创建成功: $table_log_name");
    // }
    
    // 返回创建状态
    return [
        'queue_table' => $queue_result ? true : false,
        'log_table' => $log_result ? true : false
    ];
}

关于使用核心文件 upgrade.php 的说明

代码分析:require_once(ABSPATH . 'wp-admin/includes/upgrade.php')

1. 作用

  • 引入 WordPress 核心文件 upgrade.php,该文件定义了数据库表操作的关键函数 dbDelta()
  • dbDelta() 是 WordPress 用于安全创建或更新数据库表的核心工具,它会智能对比表结构差异,执行必要的 SQL 修改(如添加/修改字段、索引),避免数据丢失。

2. 使用原因

  • 依赖关键函数dbDelta() 函数未在 WordPress 全局作用域中自动加载,必须显式引入 upgrade.php 才能使用。
  • 表结构安全更新:直接执行 CREATE TABLE 可能因表已存在而报错,dbDelta() 会自动处理:
    • 若表不存在 → 创建新表
    • 若表存在 → 检查字段/索引差异 → 仅更新差异部分
  • 符合 WordPress 规范:官方推荐使用 dbDelta() 创建插件表,确保兼容不同数据库环境(如 MySQL/MariaDB)。

3. 代码中的位置

  • 位置:在定义 SQL 语句($sql_queue, $sql_log)之后、调用 dbDelta() 之前。
  • 必要性
// 1. 定义SQL语句 
$sql_queue = "CREATE TABLE ..."; $sql_log = "CREATE TABLE ..."; 
// 2. 引入upgrade.php(使dbDelta()可用) 
require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); 
// 3. 使用dbDelta()安全创建/更新表 
$queue_result = dbDelta($sql_queue); 
// 依赖引入的文件 
$log_result = dbDelta($sql_log);

4. 是否可以移除?

  • 不可移除!移除会导致:
    1. 致命错误dbDelta() 函数未定义,脚本终止。
    2. 表创建失败:无法安全处理表结构变更。
  • 特殊情况:如果代码在 WordPress 后台(如插件安装钩子)且已加载过 upgrade.php(通常不会),可能重复引入,但 require_once 会避免重复加载,无害。

5. 关键函数 dbDelta() 说明

输入:接受完整的 CREATE TABLE SQL 语句。

输出:返回执行结果的数组(字段级操作日志)。

注意事项

SQL 必须使用 严格格式(字段定义换行、主键单独声明)。

表名需包裹反引号(`table_name`),避免关键字冲突。

示例格式:

sql CREATE TABLE `wp_example_table` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `data` varchar(100) NOT NULL, PRIMARY KEY (`id`) 
// 必须显式声明PRIMARY KEY ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

6. 总结

项目说明
作用引入 dbDelta() 函数,用于安全创建/更新数据库表。
必要性必须保留,否则代码无法工作。
位置调用 dbDelta() 之前,SQL 定义之后。
替代方案无。不使用 dbDelta() 需手动处理复杂表结构逻辑(不推荐)。
最佳实践始终在插件激活钩子中使用此代码创建表,并遵循 dbDelta() 的 SQL 格式规范。

日志数据表配套操作函数

查字段值:

//日志数据表获取指定‘log_name’字段的指定‘log_value’字段值
function zzw_get_server_status_value($log_name) {
    global $wpdb;
    $table_name = $wpdb->prefix . ZZW_TABLE_LOG_NAME;
    
    /*// 缓存优化:减少重复查询
    static $cache = [];
    $cache_key = md5($table_name . $log_name);
    
    if (isset($cache[$cache_key])) {
        return $cache[$cache_key];
    }*/

    // 使用更可靠的查询方法
    $query = $wpdb->prepare(
        "SELECT log_value FROM $table_name WHERE log_name = %s LIMIT 1",
        $log_name
    );
    
    // 添加错误抑制和结果缓存
    $log_value = $wpdb->get_var($query);
    
    // 增强错误处理
    if (null === $log_value) {
        $error_type = '';
        
        if ($wpdb->last_error) {
            // 数据库级错误
            $error_type = '数据库查询失败';
            error_log("状态查询错误 - {$log_name}: " . $wpdb->last_error);
        } else {
            // 业务级数据缺失
            $error_type = '记录不存在';
            // 降级为调试日志,避免生产环境刷屏
            if (WP_DEBUG) {
                error_log("状态查询警告 - {$log_name}: 未找到状态记录");
            }
        }
        
        // 缓存空结果避免重复查询
        // $cache[$cache_key] = false;
        return false;
    }
    
    // 缓存有效结果
    // $cache[$cache_key] = $log_value;
    return $log_value;
}

创建或修改字段:

//日志数据表数据:增、改 -----------------------------------------------
//日志数据表对应字段值的修改函数或创建数据
function zzw_update_log_value($log_name, $log_value) {
    global $wpdb;
    
    // 获取日志表名(假设常量 ZZW_TABLE_LOG_NAME 已定义)
    $table_name = $wpdb->prefix . ZZW_TABLE_LOG_NAME;
    
    // 确保名称长度不超过字段限制(varchar(20))
    //$log_name = substr($log_name, 0, 20);
    
    // 1. 检查记录是否存在
    $existing_record = $wpdb->get_row(
        $wpdb->prepare(
            "SELECT log_id FROM $table_name WHERE log_name = %s",
            $log_name
        )
    );
    
    if ($existing_record) {
        // 2. 存在记录:更新现有值
        $result = $wpdb->update(
            $table_name,
            array('log_value' => $log_value),
            array('log_id' => $existing_record->log_id),
            array('%s'),   // log_value 格式
            array('%d')    // log_id 格式
        );
        
        if (false === $result) {
            error_log("更新日志记录失败 (log_name: $log_name): " . $wpdb->last_error);
            return false;
        }
    } else {
        // 3. 不存在记录:插入新记录
        $result = $wpdb->insert(
            $table_name,
            array(
                'log_name' => $log_name,
                'log_value' => $log_value
            ),
            array('%s', '%s')  // 两个字段均为字符串格式
        );
        
        if (false === $result) {
            error_log("插入日志记录失败 (log_name: $log_name): " . $wpdb->last_error);
            return false;
        }
    }
    
    return true;
}

队列数据库插入数据函数

// 向队列数据表添加新任务
    /**
     * $type:类型标识:post term index
     * $object_id:文章ID
     * $post_type:对应的posttype名
     * */
    //已经作废
    private function zzw_add_to_queue($type, $object_id,$post_type) {
        global $wpdb;
        
        // 1. 获取队列表名(确保与创建时的表名一致)
        $table_name = $wpdb->prefix . ZZW_TABLE_NAME;
        
        // 2. 准备要插入的数据(使用当前时间)
        $current_time = current_time('mysql'); // WordPress函数获取当前时间
        
        $data = array(
            'type'       => $type,        // 任务类型  : * today - 更新当天内容 * home - 更新首页 * terms - 分类更新 * posts - 更新文章 * all - 更新全站 * clear - 清空静态
            'object_id'  => $object_id,   // 关联对象ID:文章的ID 或 term的ID 或 -1(posttype归档的ID)或 0(网站首页的ID)
            'tax_pt'     => $post_type,   // 域类型    : posttype名(对应文章或其归类) 或 taxonomy名(对应term) 或 index(对应首页)
            ..
        );
        
        // 3. 指定数据类型格式(安全防护)
        $format = array(
            '%s', // type 是字符串
            '%d', // object_id 是整数
            '%s',
            ..
        );
        
        // 4. 执行安全插入
        $result = $wpdb->insert($table_name, $data, $format);
        
        // 5. 处理结果
        if (false === $result) {
            // 插入失败处理
            error_log("[zzw_add_to_queue] ".$object_id."|".$post_type." 加入队列失败: " . $wpdb->last_error);
            return false;
        } else {
            // 返回新插入的任务ID
            return $wpdb->insert_id;
        }
    }