WordPress开发笔记

WordPress数据库操作常用语句代码及注意要点

安全获取数据表:表前缀处理

$table_name = $wpdb->prefix . TABLE_NAME;
//TABLE_NAME:如“_options”、“_posts”、“_terms”..

表前缀处理:自动适配wp_wp_2_等站点前缀

安全删除数据表

$wpdb->query("DROP TABLE IF EXISTS $table_name");

使用IF EXISTS避免不存在的表导致错误

数据表存在性检查

if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name) {
    return;
}

防止重复创建导致的SQL错误

安全创建数据表:使用dbDelta函数

global $wpdb; // 获取WordPress数据库对象
    
/**
 * 构建完整表名:
 * 1. $wpdb->prefix 获取WordPress表前缀(如wp_)
 * 2. 拼接常量 TABLE_NAME
 */
$table_name = $wpdb->prefix . TABLE_NAME;

/**
 * 检查表是否已存在:
 * 避免重复创建导致错误,提升插件健壮性
 */
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") === $table_name) {
    return; // 表已存在,无需创建
}

/**
 * 获取数据库字符集和排序规则:
 * 确保与WordPress数据库设置一致
 */
$charset_collate = $wpdb->get_charset_collate();

/**
 * SQL创建语句:
 * 1. id: 自增主键,唯一标识每个任务
 * 2. type: 任务类型(首页/分类/文章)
 * 3. object_id: 关联对象ID(0表示首页)
 * 4. status: 任务状态(待处理/处理中/完成/失败)
 * 5. created: 任务创建时间
 * 6. updated: 最后更新时间(自动更新)
 * 
 * 索引说明:
 * - PRIMARY KEY (id): 主键索引,快速定位任务
 * - KEY type_status (type, status): 复合索引,优化按类型和状态的查询
 * - KEY object_id (object_id): 单列索引,优化按对象ID的查询
 */
$sql = "CREATE TABLE $table_name (
    id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '任务唯一ID',
    type varchar(20) NOT NULL COMMENT '任务类型: home(首页), term(分类), post(文章)',
    object_id bigint(20) NOT NULL DEFAULT '0' COMMENT '关联对象ID: 首页=0, 分类=term_id, 文章=post_id',
    status varchar(20) NOT NULL DEFAULT 'pending' COMMENT '任务状态: pending(待处理), processing(处理中), completed(完成), failed(失败)',
    created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '任务创建时间',
    updated datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
    PRIMARY KEY (id),
    KEY type_status (type, status),
    KEY object_id (object_id)
) $charset_collate;";

/**
 * 包含WordPress升级API:
 * dbDelta()函数用于安全执行SQL创建/更新表结构
 * 它会智能比较现有表结构并执行必要更改
 */
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

// 执行表创建/更新
dbDelta($sql);

WordPress核心函数,智能处理表结构差异

只执行必要的ALTER TABLE操作

通过文章ID获取对应的post_type名

数据库获取方法:

global $wpdb;
        $post_type = $wpdb->get_var( $wpdb->prepare(
            "SELECT post_type FROM $wpdb->posts WHERE ID = %d", 
            $post_id
        ));

通过文章ID获取该文章别名

数据库方法:

global $wpdb;
$post_slug = $wpdb->get_var(
            $wpdb->prepare("SELECT post_name FROM $wpdb->posts WHERE ID = %d", $post_id)
        );

数据库方式分批获取当天文章

// 使用正确的时区处理方式
$timezone = get_option('timezone_string');
if ($timezone) date_default_timezone_set($timezone);

$today_start = date('Y-m-d 00:00:00');
$today_end   = date('Y-m-d 23:59:59');

$last_id = 0;// 获取起始的文章ID

// 分批:入列到数据库的队列数据表------------------------------------------------------
$batch_size = 1000;//单批获取数量
$placeholders = implode(', ', array_fill(0, count($post_types), '%s'));

//获取:查询字段ID, post_type, post_name
$sql = $wpdb->prepare(
    "SELECT ID, post_type, post_name FROM $wpdb->posts
     WHERE post_type IN ($placeholders)
       AND post_status = 'publish'
       AND CAST(post_date AS DATE) BETWEEN %s AND %s
       AND ID > %d
     ORDER BY ID ASC
     LIMIT %d",
    array_merge(
        $post_types,
        [$today_start, $today_end, $last_id, $batch_size]
    )
);

$results = $wpdb->get_results($sql);
/* 获取结果示例:
Array
(
    [0] => stdClass Object
        (
            [ID] => 3200
            [post_type] => 'post'
            [post_name] => 'hello-world'
        )
    [1] => stdClass Object
        (
            [ID] => 3202
            [post_type] => 'page'
            [post_name] => 'about-us'
        )
    [2] => stdClass Object
        (
            [ID] => 3204
            [post_type] => 'product'
            [post_name] => 'tshirt-2023'
        )
)
*/

if (!empty($results)) {
    foreach ($results as $row) {
        //你的操作
    }
}

// 恢复原始时区
if ($timezone) date_default_timezone_set('UTC');