
本文详解如何在 WordPress 插件中正确使用 $wpdb 进行数据库插入(INSERT)和更新(UPDATE)操作,重点纠正 prepare() 误用导致查询失效的问题,并提供防 SQL 注入、错误处理及最佳实践。
本文详解如何在 wordpress 插件中正确使用 `$wpdb` 进行数据库插入(insert)和更新(update)操作,重点纠正 `prepare()` 误用导致查询失效的问题,并提供防 sql 注入、错误处理及最佳实践。
在 WordPress 自定义插件开发中,直接操作数据库是常见需求,但若未遵循 $wpdb 的规范用法,极易导致查询静默失败(如 prepare() 被误当作执行方法调用)。原代码中核心错误在于:$wpdb->prepare() 仅用于预处理 SQL 语句并返回已转义的字符串,它本身并不执行查询——必须配合 $wpdb->query()、$wpdb->update() 或 $wpdb->insert() 等执行方法才能生效。
以下为修复后的专业写法(含安全性、健壮性与可维护性优化):
Word报告自动生成神器。自动生成专业Word文档报告,支持模板填充、目录生成、表格/图表插入、页眉页脚、多级标题、样式主题、批量邮件合并。当用户需要生成Word报告、创建合同文档、批量生成通知/证书、填充Word模板、制作商业计划书时触发。
✅ 正确写法:使用 prepare() + 执行方法 + 错误检查
function main() {
// 仅处理 POST 请求(避免 GET 泄露敏感数据)
if (!isset($_POST['task_current_time']) || !isset($_POST['task_current_title'])) {
return;
}
global $wpdb;
$table_name = $this->tablenamev2; // 确保已定义且合法
$taskTime = sanitize_text_field($_POST['task_current_time']);
$taskTitle = sanitize_text_field($_POST['task_current_title']);
// ✅ 安全查询:使用 prepare() 生成参数化 SQL,再用 get_var() 检查是否存在
$exists = $wpdb->get_var(
$wpdb->prepare("SELECT COUNT(*) FROM {$table_name} WHERE task_current_title = %s", $taskTitle)
);
if ($exists > 0) {
// ✅ 更新:使用 update() 方法(自动 prepare + 执行 + 返回影响行数)
$result = $wpdb->update(
$table_name,
['task_current_time' => $taskTime], // SET 字段
['task_current_title' => $taskTitle], // WHERE 条件
['%s'], // 数据类型:string
['%s'] // WHERE 字段类型
);
if (false === $result) {
error_log('WPDB Update failed: ' . $wpdb->last_error);
} else {
error_log("Updated {$result} row(s)");
}
} else {
// ✅ 插入:使用 insert() 方法(更安全、自动 escape)
$result = $wpdb->insert(
$table_name,
[
'task_current_time' => $taskTime,
'task_current_title' => $taskTitle
],
['%s', '%s'] // 对应字段类型
);
if (false === $result) {
error_log('WPDB Insert failed: ' . $wpdb->last_error);
} else {
error_log("Inserted new record with ID: {$wpdb->insert_id}");
}
}
}
⚠️ 关键注意事项:
- prepare() 不执行查询:它只返回预处理后的 SQL 字符串(如 "SELECT * FROM wp_mytable WHERE title = 'abc'"),需显式调用 query()、get_var() 等执行。
- 禁止字符串拼接 SQL:原代码中 WHERE task_current_title = '$taskTitle' 存在严重 SQL 注入风险,必须改用 %s 占位符 + prepare()。
- 优先使用高级方法:$wpdb->insert() 和 $wpdb->update() 内部已集成 prepare() 和执行逻辑,比手动组合更安全、简洁。
- 始终验证输入:使用 sanitize_text_field()、esc_sql()(仅必要时)等过滤用户输入。
- 启用调试:开发阶段建议在 wp-config.php 中设置 define('WP_DEBUG', true); 并开启数据库错误日志。
? 总结
WordPress 的 $wpdb 是强大而严谨的数据库接口,其设计哲学是“分离准备与执行”。牢记:prepare() 是“厨师备料”,query()/insert()/update() 才是“下锅炒菜”。坚持参数化查询、善用封装方法、添加错误日志,即可写出既安全又可靠的数据库操作逻辑。










