WordPress插件开发核心技能 wordpress-plugin-core

本技能提供WordPress插件开发的全面指南,涵盖安全基础、代码架构、常见实现模式和故障排除。重点包括SQL注入、XSS、CSRF等安全防护,以及REST API、自定义文章类型等高级功能。关键词:WordPress插件开发、安全防护、REST API、自定义文章类型、数据库查询、钩子、非令牌验证、代码架构、故障排除。

后端开发 0 次安装 0 次浏览 更新于 3/7/2026

名称: wordpress-plugin-core 描述: WordPress插件开发,包含钩子、安全、REST API、自定义文章类型。适用于插件创建、$wpdb查询、Settings API,或遇到SQL注入、XSS、CSRF、nonce错误。

关键词: wordpress插件开发, wordpress安全, wordpress钩子, wordpress过滤器, wordpress数据库, wpdb准备, sanitize_text_field, esc_html, wp_nonce, 自定义文章类型, register_post_type, settings api, rest api, admin-ajax, wordpress sql注入, wordpress xss, wordpress csrf, 插件头, 激活钩子, 停用钩子, wordpress编码标准, wordpress插件架构 许可证: MIT

WordPress插件开发(核心)

状态: 生产就绪 最后更新: 2025-11-27 依赖项: 无(WordPress 5.9+, PHP 7.4+) 最新版本: WordPress 6.7+, PHP 8.0+ 推荐


快速开始(10分钟)

1. 选择插件结构

提供三种架构模式(详见 references/plugin-architectures.md 获取详细示例):

  • 简单(仅函数) - 小型插件,函数少于5个
  • OOP - 中型插件,功能相关
  • PSR-4(命名空间 + Composer) - 现代标准(2025年),最易维护

2. 创建插件头

每个插件必须在主文件中有一个头注释:

<?php
/**
 * 插件名称:       我的超赞插件
 * 描述:         简短描述。
 * 版本:          1.0.0
 * 最低要求:      5.9
 * 要求PHP:       7.4
 * 文本域:        my-plugin
 */

if ( ! defined( 'ABSPATH' ) ) exit;

关键: 插件名称必需,文本域必须与插件slug完全匹配。

3. 安全基础(5个要点)

// 1. 唯一前缀(4-5字符)
function mypl_init() { /* 代码 */ }
add_action( 'init', 'mypl_init' );

// 2. ABSPATH检查(每个文件)
if ( ! defined( 'ABSPATH' ) ) exit;

// 3. Nonces用于表单
wp_nonce_field( 'mypl_action', 'mypl_nonce' );

// 4. 清理输入,转义输出
$clean = sanitize_text_field( $_POST['input'] );
echo esc_html( $output );

// 5. 预处理语句
$wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}table WHERE id = %d", $id ) );

五步安全基础

步骤1: 所有内容使用唯一前缀

规则: 最少4-5字符,应用于函数、类、常量、选项、瞬态、元键。避免 wp____

// 良好
function mypl_init() {}
class MyPL_Settings {}
add_option( 'mypl_option', 'value' );

// 错误 - 会冲突
function init() {}
class Settings {}

步骤2: 检查权限,而非仅管理员状态

// 错误
if ( is_admin() ) { /* 安全漏洞 */ }

// 正确
if ( current_user_can( 'manage_options' ) ) { /* 安全 */ }

常用权限: manage_options(管理员)、edit_posts(编辑)、publish_posts(作者)

步骤3: 安全三要素

输入 → 处理 → 输出(清理 → 验证 → 转义):

// 清理(输入)
$name = sanitize_text_field( $_POST['name'] );
$email = sanitize_email( $_POST['email'] );
$url = esc_url_raw( $_POST['url'] );
$html = wp_kses_post( $_POST['content'] );

// 验证(逻辑)
if ( ! is_email( $email ) ) wp_die( '无效邮箱' );

// 转义(输出)
echo esc_html( $name );
echo '<a href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';

规则: 清理输入,转义输出。永远不要信任用户数据。

步骤4: Nonces(CSRF防护)

一次性令牌,证明请求来自您的网站。

// 表单
<form method="post">
    <?php wp_nonce_field( 'mypl_action', 'mypl_nonce' ); ?>
    <input type="text" name="data" />
</form>

// 验证
if ( ! wp_verify_nonce( $_POST['mypl_nonce'], 'mypl_action' ) ) wp_die( '安全检查失败' );

// AJAX
check_ajax_referer( 'mypl-ajax-nonce', 'nonce' );

步骤5: 数据库的预处理语句

关键: 对于用户输入,始终使用 $wpdb->prepare()

// 错误 - SQL注入
$wpdb->get_results( "SELECT * FROM {$wpdb->prefix}table WHERE id = {$_GET['id']}" );

// 正确
$wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}table WHERE id = %d", $_GET['id'] ) );

占位符: %s(字符串)、%d(整数)、%f(浮点数)

LIKE查询: 在添加通配符前使用 $wpdb->esc_like()

$search = '%' . $wpdb->esc_like( $term ) . '%';
$wpdb->get_results( $wpdb->prepare( "... WHERE title LIKE %s", $search ) );

关键规则

必须做

使用唯一前缀(4-5字符)用于所有全局代码(函数、类、选项、瞬态) ✅ 添加ABSPATH检查到每个PHP文件:if ( ! defined( 'ABSPATH' ) ) exit;检查权限current_user_can()),而不仅仅是 is_admin()验证nonces用于所有表单和AJAX请求 ✅ 使用 $wpdb->prepare() 用于所有带用户输入的数据库查询 ✅ 清理输入,使用 sanitize_*() 函数在保存前 ✅ 转义输出,使用 esc_*() 函数在显示前 ✅ 刷新重写规则在激活时当注册自定义文章类型 ✅ 使用uninstall.php用于永久清理(而非停用钩子) ✅ 遵循WordPress编码标准(缩进用制表符,Yoda条件)

禁止做

永不使用 extract() - 创建安全漏洞 ❌ 永不信任 $_POST/$_GET 而不清理 ❌ 永不相接用户输入到SQL - 始终使用 prepare() ❌ 永不单独使用 is_admin() 用于权限检查 ❌ 永不输出未清理数据 - 始终转义 ❌ 永不使用通用函数/类名 - 始终加前缀 ❌ 永不使用短PHP标签 <?<?= - 只使用 <?php永不在停用时删除用户数据 - 仅在卸载时 ❌ 永不多次注册卸载钩子 - 仅在激活时一次 ❌ 永不在主流程中使用 register_uninstall_hook() - 改用 uninstall.php


已知问题预防

此技能预防 20 个记录的问题:

问题 #1: SQL注入

错误: 通过未转义的用户输入损害数据库 来源: https://patchstack.com/articles/sql-injection/(15% 的漏洞) 原因: 直接相接到SQL查询中 预防: 始终使用 $wpdb->prepare() 带占位符

// 易受攻击
$wpdb->query( "DELETE FROM {$wpdb->prefix}table WHERE id = {$_GET['id']}" );

// 安全
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}table WHERE id = %d", $_GET['id'] ) );

问题 #2: XSS(跨站脚本)

错误: 在用户浏览器中执行恶意JavaScript 来源: https://patchstack.com(35% 的漏洞) 原因: 输出未清理的用户数据到HTML 预防: 始终使用上下文适当的函数转义输出

// 易受攻击
echo $_POST['name'];
echo '<div class="' . $_POST['class'] . '">';

// 安全
echo esc_html( $_POST['name'] );
echo '<div class="' . esc_attr( $_POST['class'] ) . '">';

问题 #3: CSRF(跨站请求伪造)

错误: 未经授权操作以用户名义执行 来源: https://blog.nintechnet.com/25-wordpress-plugins-vulnerable-to-csrf-attacks/ 原因: 无验证请求来自您的网站 预防: 使用nonces配合 wp_nonce_field()wp_verify_nonce()

// 易受攻击
if ( $_POST['action'] == 'delete' ) {
    delete_user( $_POST['user_id'] );
}

// 安全
if ( ! wp_verify_nonce( $_POST['nonce'], 'mypl_delete_user' ) ) {
    wp_die( '安全检查失败' );
}
delete_user( absint( $_POST['user_id'] ) );

问题 #4: 缺少权限检查

错误: 普通用户可以访问管理功能 来源: WordPress安全审查指南 原因: 使用 is_admin() 而非 current_user_can() 预防: 始终检查权限,而非仅管理员上下文

// 易受攻击
if ( is_admin() ) {
    // 任何登录用户都能触发
}

// 安全
if ( current_user_can( 'manage_options' ) ) {
    // 仅管理员能触发
}

问题 #5: 直接文件访问

错误: PHP文件在WordPress上下文外执行 来源: WordPress插件手册 原因: 文件顶部无ABSPATH检查 预防: 添加ABSPATH检查到每个PHP文件

// 添加到每个PHP文件顶部
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

附加问题 (#6-20)

对于超出前5个安全漏洞的全面错误覆盖,加载 references/error-catalog.md,其中包括:

  • 功能性: 前缀冲突、重写规则未刷新、已弃用函数、文本域不匹配、插件依赖、自动保存触发
  • 性能: 脚本到处加载、瞬态未清理、admin-ajax.php性能
  • 安全: 保存时缺少清理、不正确的LIKE查询、使用extract()、缺少REST API权限回调、卸载钩子问题
  • 数据完整性: 停用时删除数据

每个问题包括:错误描述、来源、原因、预防代码、影响严重性、频率。


插件架构模式

为您的插件大小和复杂性选择正确的架构:

决策指南

简单(仅函数)

  • 何时: 小型插件(<5函数)、单一功能
  • 优点: 易于开始、最小样板
  • 缺点: 不扩展、组织超过~5函数困难
  • 示例: 简单短代码插件、基本小工具

OOP(单例模式)

  • 何时: 中型插件(5-20函数)、相关功能
  • 优点: 更好组织、封装、可测试
  • 缺点: 比简单多样板、不使用现代PHP特性
  • 示例: 自定义文章类型插件、管理设置页面

PSR-4(命名空间 + Composer)

  • 何时: 大型/现代插件、团队开发、2025+ 标准
  • 优点: 现代PHP、命名空间、自动加载、最佳实践
  • 缺点: 需要Composer、更多初始设置
  • 示例: 电子商务扩展、多功能插件

完整示例

对于完整的实现示例、目录结构、激活钩子和代码模式,加载 references/plugin-architectures.md


常见实现模式

此技能提供8个常见WordPress插件功能的生产就绪模式:

  1. 自定义文章类型 - 注册带Gutenberg支持的CPT、刷新重写规则
  2. 自定义分类法 - 分层(分类)或平面(标签)分类法
  3. 元框 - 保存自定义字段带适当安全(nonces、权限、自动保存检查)
  4. Settings API - WordPress原生设置页面带清理
  5. REST API端点 - 现代API端点带权限回调和验证
  6. AJAX处理器 - 传统admin-ajax.php模式(新项目使用REST API)
  7. 自定义数据库表 - 创建表带dbDelta、版本控制
  8. 瞬态用于缓存 - 缓存昂贵操作、更新时清理

对于完整实现代码,在实现任何这些功能时加载 references/common-patterns.md。每个模式包括:

  • 完整工作代码示例
  • 安全要求清单
  • 常见错误避免
  • 最佳实践和性能提示


分发和自动更新

托管在WordPress.org外的插件可以使用 Plugin Update Checker 由 YahnisElsts(推荐)提供自动更新。

快速解决方案:

  • 公开仓库: Plugin Update Checker(GitHub/GitLab/BitBucket)
  • 私有插件: Plugin Update Checker + 认证令牌
  • 商业插件: Freemius 或 自定义更新服务器
  • 无需编码: Git Updater插件

对于完整实现,加载 references/github-auto-updates.md,其中包括:

  • Plugin Update Checker设置(5分钟)
  • GitHub发布工作流
  • 私有仓库认证
  • 安全最佳实践(校验和、令牌、速率限制)
  • 替代方案比较
  • ZIP结构要求

依赖项

必需:

  • WordPress 5.9+(推荐6.7+)
  • PHP 7.4+(推荐8.0+)

可选:

  • Composer 2.0+ - 用于PSR-4自动加载
  • WP-CLI 2.0+ - 用于命令行插件管理
  • Query Monitor - 用于调试和性能分析

官方文档


故障排除

致命错误: 启用 WP_DEBUG,检查 wp-content/debug.log,验证带前缀的名称

CPT上404: 刷新重写规则(临时在wp-admin中添加 flush_rewrite_rules();

Nonce失败: 检查匹配名称、正确操作、24小时过期

AJAX返回0/-1: 验证操作名称匹配 wp_ajax_{action}、nonce发送/验证、处理器钩住

HTML被剥离: 使用 wp_kses_post() 而非 sanitize_text_field()

数据库查询失败: 始终使用 $wpdb->prepare(),包括 $wpdb->prefix,验证语法


何时加载参考文件

此技能使用 渐进式披露 - 主文件包含要点,参考文件有详细实现。根据您当前任务加载参考:

references/common-patterns.md(465行)

何时加载: 实现特定WordPress功能时 包含:

  • 自定义文章类型(注册、Gutenberg支持、重写规则)
  • 自定义分类法(分层 vs 平面、REST API)
  • 元框(安全要求、保存钩子、自动保存检查)
  • Settings API(register_setting、部分、字段层次)
  • REST API端点(权限回调、验证、响应)
  • AJAX处理器(nonce验证、wp_ajax钩子、JavaScript集成)
  • 自定义数据库表(dbDelta、字符编码、版本控制)
  • 瞬态用于缓存(缓存模式、失效、过期)

references/plugin-architectures.md(220行)

何时加载: 选择插件结构或模式间迁移时 包含:

  • 简单模式(仅函数,<5函数)
  • OOP模式(单例、封装、中型插件)
  • PSR-4模式(命名空间、Composer自动加载、现代标准)
  • 模式选择决策树
  • 完整目录结构带所有文件
  • 激活/停用钩子示例
  • 模式间迁移路径

references/error-catalog.md(问题 #6-20,573行)

何时加载: 调试超出前5个安全漏洞的问题时 包含:

  • 功能性问题(前缀冲突、重写规则、已弃用函数、文本域、依赖项、自动保存)
  • 性能问题(脚本到处、瞬态清理、admin-ajax.php替代方案)
  • 安全问题(清理、extract()、REST权限、卸载钩子)
  • 数据完整性问题(停用 vs 卸载) 每个问题包括: 错误描述、来源/参考、原因、预防代码、影响严重性、频率

references/advanced-topics.md(150行)

何时加载: 实现i18n、WP-CLI、定时任务或依赖检查时 包含:

  • 国际化(i18n)- load_plugin_textdomain()、翻译工作流、.pot/.po/.mo文件
  • WP-CLI命令 - 自定义命令创建、进度条、输出函数
  • 定时事件(定时)- wp_schedule_event()、自定义计划、激活钩子
  • 插件依赖检查 - 版本要求、软依赖、用户友好错误消息

references/security-checklist.md(527行)

何时加载: 执行安全审计或代码审查漏洞时 包含:

  • 完整安全审计清单
  • OWASP Top 10 for WordPress
  • 每种漏洞类型代码示例
  • 测试过程和工具
  • 安全插件推荐

references/github-auto-updates.md(1,224行)

何时加载: 为托管在WordPress.org外的插件设置自动更新时 包含:

  • Plugin Update Checker(推荐)- 5分钟设置
  • GitHub发布工作流和自动化
  • 私有仓库认证(令牌、wp-config.php)
  • 替代方案(Git Updater、自定义服务器、Freemius)
  • 安全最佳实践(校验和、签名、速率限制)
  • ZIP结构要求和常见错误
  • 部署自动化示例

references/common-hooks.md(234行)

何时加载: 使用WordPress钩子时需要参考时 包含:

  • 动作钩子参考(init、admin_menu、save_post等)
  • 过滤器钩子参考(the_content、post_type_args等)
  • 钩子优先级和执行顺序
  • 常见钩子组合和模式

完整设置清单

使用此清单验证您的插件:

  • [ ] 插件头完整带所有字段
  • [ ] ABSPATH检查在每个PHP文件顶部
  • [ ] 所有函数/类使用唯一前缀
  • [ ] 所有表单有nonce验证
  • [ ] 所有用户输入被清理
  • [ ] 所有输出被转义
  • [ ] 所有数据库查询使用 $wpdb->prepare()
  • [ ] 权限检查(而不仅仅是 is_admin())
  • [ ] 自定义文章类型在激活时刷新重写规则
  • [ ] 停用钩子仅清除临时数据
  • [ ] uninstall.php处理永久清理
  • [ ] 文本域匹配插件slug
  • [ ] 脚本/样式仅在需要时加载
  • [ ] 开发期间启用 WP_DEBUG
  • [ ] 使用 Query Monitor 插件测试性能
  • [ ] 无已弃用函数警告
  • [ ] 与最新WordPress版本兼容

问题?疑问?

  1. 检查 references/error-catalog.md 获取附加问题 #6-20
  2. 验证安全基础所有步骤
  3. 检查官方文档: https://developer.wordpress.org/plugins/
  4. 启用 WP_DEBUG 并检查 debug.log
  5. 使用 Query Monitor 插件调试钩子和查询