vr-shopxo-plugin/plan.md

99 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Plan — 调试 "Undefined array key 'id'" PHP 错误
> 版本v1.2 | 日期2026-04-20 | Agentcouncil/BackendArchitect + council/DebugAgent并行协作
> 关联提交bbea35d83feat: 保存时自动填充 template_snapshot
---
## 任务概述
调试 ShopXO 后台编辑票务商品goods_id=118保存时报错
```
Undefined array key "id"
```
根因代码位于 `bbea35d83` 新增的 `AdminGoodsSaveHandle.php` save_thing_end 时机。
---
## 任务清单
- [x] [Done: council/BackendArchitect] **Task 1**: 根因定位 — 逐行分析所有 "id" 访问位置
- [x] [Done: council/BackendArchitect] **Task 2**: Db::name() 表前缀问题 — ShopXO 插件表前缀行为确认
- [x] [Done: council/BackendArchitect] **Task 3**: 根因 1 — `$r['id']` 空安全AdminGoodsSaveHandle 第 77 行)
- [x] [Done: council/BackendArchitect] **Task 4**: 根因 2 — `find()` 返回 null 的空安全AdminGoodsSaveHandle 第 71 行)
- [x] [Done: council/BackendArchitect] **Task 5**: 根因 3 — `$config['template_id']` / `selected_rooms` 数据类型问题
- [x] [Done: council/BackendArchitect] **Task 6**: SeatSkuService::BatchGenerate 类似问题审计
- [x] [Done: council/BackendArchitect] **Task 7**: 修复方案汇总 + 建议修复优先级
- [x] [Done: council/BackendArchitect] **Task 8**: 将修复方案写入 `reviews/BackendArchitect-on-Issue-13-debug.md`
- [x] [Done: council/DebugAgent] **Task 9**: Round 1 静态分析 → `reviews/DebugAgent-PRELIMINARY.md`
- [x] [Done: council/DebugAgent] **Task 10**: Round 2 — 验证 database.php 前缀配置 + 读取 Admin.php 第 66 行
- [x] [Done: council/DebugAgent] **Task 11**: Round 2 — 编写 DebugAgent 最终根因报告 → `reviews/DebugAgent-ROOT_CAUSE.md`
- [x] [Done: council/BackendArchitect] **Task 12**: Round 2 — 评审 DebugAgent ROOT_CAUSE 报告 → `reviews/BackendArchitect-on-DebugAgent-ROOT_CAUSE.md`
- [x] [Done: council/SecurityEngineer] **Task 13**: Round 2 — 独立安全审计6项子任务`reviews/SecurityEngineer-AUDIT.md`
- Q1: "Undefined array key 'id'" 最可能出现的行 → Primary: Line 77
- Q2: Db::name() 表前缀行为 → 等价,排除
- Q3: find() 返回 null 处理 → Secondary: Line 71
- Q4: $configs JSON 解码类型安全 → 部分安全
- Q5: selected_rooms 数据结构 → 类型正确但无空安全
- Q6: BatchGenerate + item_type → 安全
---
## 阶段划分
| 阶段 | 内容 |
|------|------|
| **Draft** | ✅ Task 1-6BackendArchitect+ Task 9DebugAgent+ Task 13SecurityEngineer|
| **Review** | ✅ Task 7BackendArchitect+ Task 11DebugAgent+ Task 12BackendArchitect|
| **Finalize** | ✅ Task 8 + Task 12 + Task 13所有评审报告输出完毕 |
---
## 根因结论(已验证)
1. **Primary99%**: `AdminGoodsSaveHandle.php:77``$r['id']` 无空安全rooms 中缺少 id key 时崩溃
2. **Secondary5%**: `AdminGoodsSaveHandle.php:71``find()` 返回 null 后直接访问 `$template['seat_map']`
3. **Tertiary静默**: `AdminGoodsSaveHandle.php:77``selected_rooms` 类型不匹配,`in_array` 永远 false
4. **已排除**: 表前缀问题 — `Db::name()``BaseService::table()` 均查询 `vrt_vr_seat_templates`,等价
5. **已排除**: SeatSkuService::BatchGenerate — 第 100 行已有 `!empty()` 空安全 fallback
6. **SecurityEngineer 补充**: PHP 8+ 中 `null['key']` 抛出 `TypeError`(非 Warning`$configs` JSON 解码有 `is_array` 防御;`item_type` 有 `?? ''` 兜底;修复建议已在 `reviews/SecurityEngineer-AUDIT.md`
## DebugAgent 补充结论Round 1
6. **PHP 8+ `??` 行为**`$template['seat_map'] ?? '{}'` 对空数组 `[]` 的键访问**无效**,需用 `isset()`
7. **vr_goods_config JSON 解码**:有 `is_array()` 防御,访问 `$config['template_id']` 安全
---
## 执行顺序DebugAgent Round 2
```
Task 10: 读 shopxo/config/database.php → 确认 prefix 值;读 Admin.php 第 66 行
Task 11: 综合输出 reports/DebugAgent-ROOT_CAUSE.md
```
---
## 关键文件(只读)
| 文件 | 关注点 |
|------|--------|
| `shopxo/app/plugins/vr_ticket/hook/AdminGoodsSaveHandle.php` | save_thing_end 逻辑template_snapshot 填充代码 |
| `shopxo/app/plugins/vr_ticket/service/SeatSkuService.php` | BatchGenerate、ensureAndFillVrSpecTypes |
| `shopxo/app/plugins/vr_ticket/service/BaseService.php` | table() 前缀方法 |
| `shopxo/config/database.php` | ShopXO 数据库表前缀配置Task 10 需读) |
| `docs/VR_GOODS_CONFIG_SPEC.md` | vr_goods_config v3.0 JSON 格式 |
| `docs/PHASE2_PLAN.md` | 项目背景 |
---
## 修复记录
- [x] **Fix Commit**: `804d465d0` — P1+P2 空安全修复已合并到 main
- `AdminGoodsSaveHandle.php:71-73`:新增 `if (empty($template)) { continue; }`
- `AdminGoodsSaveHandle.php:80``$r['id']` 前加 `isset()` 空安全
- 合并到 main`49930844f`