vr-shopxo-plugin/plan.md

4.9 KiB
Raw Blame History

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 时机。


任务清单

  • [Done: council/BackendArchitect] Task 1: 根因定位 — 逐行分析所有 "id" 访问位置

  • [Done: council/BackendArchitect] Task 2: Db::name() 表前缀问题 — ShopXO 插件表前缀行为确认

  • [Done: council/BackendArchitect] Task 3: 根因 1 — $r['id'] 空安全AdminGoodsSaveHandle 第 77 行)

  • [Done: council/BackendArchitect] Task 4: 根因 2 — find() 返回 null 的空安全AdminGoodsSaveHandle 第 71 行)

  • [Done: council/BackendArchitect] Task 5: 根因 3 — $config['template_id'] / selected_rooms 数据类型问题

  • [Done: council/BackendArchitect] Task 6: SeatSkuService::BatchGenerate 类似问题审计

  • [Done: council/BackendArchitect] Task 7: 修复方案汇总 + 建议修复优先级

  • [Done: council/BackendArchitect] Task 8: 将修复方案写入 reviews/BackendArchitect-on-Issue-13-debug.md

  • [Done: council/DebugAgent] Task 9: Round 1 静态分析 → reviews/DebugAgent-PRELIMINARY.md

  • [Done: council/DebugAgent] Task 10: Round 2 — 验证 database.php 前缀配置 + 读取 Admin.php 第 66 行

  • [Done: council/DebugAgent] Task 11: Round 2 — 编写 DebugAgent 最终根因报告 → reviews/DebugAgent-ROOT_CAUSE.md

  • [Done: council/BackendArchitect] Task 12: Round 2 — 评审 DebugAgent ROOT_CAUSE 报告 → reviews/BackendArchitect-on-DebugAgent-ROOT_CAUSE.md

  • [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:71find() 返回 null 后直接访问 $template['seat_map']
  3. Tertiary静默: AdminGoodsSaveHandle.php:77selected_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

  1. PHP 8+ ?? 行为$template['seat_map'] ?? '{}' 对空数组 [] 的键访问无效,需用 isset()
  2. 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 项目背景

修复记录

  • Fix Commit: 804d465d0 — P1+P2 空安全修复已合并到 main
    • AdminGoodsSaveHandle.php:71-73:新增 if (empty($template)) { continue; }
    • AdminGoodsSaveHandle.php:80$r['id'] 前加 isset() 空安全
    • 合并到 main49930844f