用户要求为「插件开发」版块写一则原创帖子。要求如下:
段落)。 2. 标题必须具体、有信息量,禁止套用同一固定句式反复生成。 3. 不要解释、不要提问。 4. 语言贴合开发者交流,可贴关键代码片段,不要过于书面官方。 5. 本次强制写作角度:发布清单:上线前 Checklist(权限、路由、菜单、配置) 6. 多样性标记:20260908063001-4a83(仅用于确保本次与历史不同,不要写进正文) 7. 硬性要求: - 标题必须与已发布标题明显不同,禁止复用相同主标题或仅改个别字; - 正文结构、案例、小节标题也要与已有文差异明显; - 第一行标题,空一行后正文。 已发布标题中已有多个关于上线前Checklist的: - 5. 插件发版前最后一晚,我打印了这张"四色标记纸"贴在显示器上:权限、路由、菜单、配置逐项过 - 9. 插件上线前「四域联检」:我是怎么把权限、路由、菜单、配置串成一条可执行的验收链的 - 19. 插件上线前夜,我靠这份"反向破坏"清单逼出了三个隐藏漏洞:从"假装自己是攻击者"的角度做最后一轮验收 主题是"发布清单:上线前 Checklist(权限、路由、菜单、配置)",需要换一个全新切入点,与已有文章差异明显。 已有文章切入点: - 5:四色标记纸,贴在显示器上逐项过 - 9:四域联检,串成可执行验收链 - 19:反向破坏清单,假装攻击者 我需要找一个全新的切入点来写同一个主题。可能的切入点: - 从"自动化脚本"角度:把Checklist写成自动化测试脚本/CLI命令 - 从"团队协作"角度:Code Review时的Checklist模板 - 从"版本比对"角度:用diff工具比对上次发布和本次发布的配置差异 - 从"最小权限原则"角度:逐项审计每个配置项是否过度授权 - 从"沙盒预演"角度:在staging环境按清单做"破坏性演练" - 从"脑图/思维导图"角度:把四个维度做成可勾选的脑图节点 - 从"时间线"角度:上线前30分钟、10分钟、5分钟的Checklist执行节奏 - 从"意外回滚"角度:Checklist不仅包含上线,还包含"如何30秒内回滚" - 从"多站点网络"角度:在 multisite 环境下的Checklist特殊项 - 从"配置漂移"角度:用代码对比数据库实际值与默认值 需要标题具体、有信息量,不能套用固定句式。 让我想一个与"四色标记纸"、"四域联检"、"反向破坏"都不同的角度。 切入点 idea:把 Checklist 做成一个可复用的 JSON/YAML 结构,甚至是一个小的 PHP 数组,每次发版前跑一遍断言。或者更接地气一点:"我把上线前的 Checklist 塞进了 `phpunit` 里,让机器替我盯权限、路由、菜单、配置"。 这个角度很开发者,有代码片段,与已有的"纸质清单"、"验收链"、"攻击者视角"都不同。 标题构思: - 我把上线前的 Checklist 写成了 PHPUnit 的 `@group preflight`,让机器替我盯着权限、路由、菜单、配置 - 不想上线后手抖,我把四域检查编成了一组"发版前断言" - 别再对着纸质清单打钩了:我用一段 PHP 断言把权限、路由、菜单、配置变成了自动化预检 - 插件发版前的"自动驾驶":我是如何用一组预检脚本把权限、路由、菜单、配置变成自动断言的 - 把"人肉Checklist"装进CI:我写的插件发版前预检脚本长这样 检查与已有标题的相似度: - 5提到"四色标记纸", mine是自动化/脚本/断言 - 9提到"四域联检", mine是脚本化 - 19提到"反向破坏", mine是自动化预检 看起来不错。选择一个具体的: "插件发版前的'自动驾驶':我是如何用一组预检脚本把权限、路由、菜单、配置变成自动断言的" 或者更口语化: "别再贴便利贴了:我把上线前的权限、路由、菜单、配置检查写进了 `phpunit` 预检组" 再想一个更独特的: "上线前最后一道闸机:我如何用 `WP_UnitTestCase` 把权限、路由、菜单、配置做成可回滚的断言检查" 让我确定一个最有区分度的: **我把上线前的"四域检查"写成了 PHPUnit 的 `@group preflight`,让机器替我盯权限、路由、菜单、配置** 这个标题具体,有技术细节(PHPUnit, @group preflight),有主题(四域检查/权限路由菜单配置),与已有标题完全不同。 正文结构: - 引言:吐槽纸质 checklist 容易遗漏,尤其是半夜发版脑子不清醒 - 第一部分:权限检查 - 用 WP_UnitTestCase 断言 capability 存在且未过度分配 - 第二部分:路由检查 - 断言 REST 路由已注册且 namespace 正确,检查 rewrite 规则已刷新 - 第三部分:菜单检查 - 断言 menu slug 已注册且与 capability 绑定一致 - 第四部分:配置检查 - 断言 options 默认值已写入,且类型正确 - 结尾:附上完整代码骨架,说明如何在 CI 里跑 注意要用 `
` 段落。 需要包含关键代码片段。 确保正文结构、案例、小节标题与已有文差异明显。已有文章: - 5:四色标记纸(红绿黄蓝),逐项过,纸质 - 9:四域联检,验收链,流程化 - 19:反向破坏,攻击者视角 我的是:自动化测试脚本,PHPUnit,代码断言。 正文组织:
上周赶一个版本,凌晨两点脑子糊了,把 `manage_my_plugin` 权限配给了 `editor`,结果早上用户后台直接炸锅。那之后我就把"发版前人工打钩"这套扔了——人会在半夜犯错,但 PHPUnit 不会。
现在我插件仓库里多了个 `tests/preflight/` 目录,专门放"预检断言"。每次打 tag 之前,CI 先跑一遍 `@group preflight`,权限、路由、菜单、配置四项全由机器过。分享下我目前用的几组断言,直接 copy 就能改。
1. 权限:别只测"有没有",要测"有没有给错人"
之前踩的坑不是 capability 没注册,而是 `add_cap` 时第三个参数手滑写成了 `true`,直接下放给了 Subscriber。现在我的权限预检长这样:
public function test_capabilities_are_not_over_granted() {
$roles = ['administrator', 'editor', 'author', 'contributor', 'subscriber'];
$cap = 'my_plugin_export_data'; // 高敏感操作
foreach ($roles as $role_name) {
$role = get_role($role_name);
if ('administrator' === $role_name) {
$this->assertTrue($role->has_cap($cap), '管理员必须拥有导出权限');
} else {
$this->assertFalse($role->has_cap($cap), "高敏感权限不得下放给 {$role_name}");
}
}
}
2. 路由:注册成功不等于能访问
REST 路由在 `rest_api_init` 里 `register_rest_route` 写得很嗨,一换 permalink 结构或者忘了 `flush_rewrite_rules`,前端就 404。我现在的预检会双保险:
public function test_critical_rest_routes_exist() {
$routes = rest_get_server()->get_routes();
$this->assertArrayHasKey('/my-plugin/v1/jobs', $routes, 'Job 接口必须注册');
// 顺便测一下权限回调真的挂上了,不是走默认的 "edit_posts"
$route = $routes['/my-plugin/v1/jobs'][0];
$this->assertNotEquals('__return_true', $route['permission_callback'], '禁止裸奔');
}
3. 菜单:slug 和 capability 必须"对齿"
后台菜单最烦的是 `add_menu_page` 的 slug 和 `current_user_can` 的 capability 对不上,结果菜单一闪而过或者点进去报无权访问。我直接读 `$GLOBALS['menu']` 和 `$GLOBALS['submenu']` 做断言:
public function test_admin_menu_capability_alignment() {
global $menu, $submenu;
// 强制把当前用户设成编辑,验证最小可见权限
wp_set_current_user(self::factory()->user->create(['role' => 'editor']));
$found = false;
foreach ($menu as $item) {
if ('my-plugin-dashboard' === $item[2]) {
$this->assertEquals('my_plugin_view_dashboard', $item[1], '菜单 capability 必须严格

