用 Kiro 将 PHP 迁移 Java 变成可验证流程
文章以原 PHP 应用为行为规范,结合机械式发现扫描器、八阶段工作流和行为一致性验证框架,组织 Java 迁移。重点是让迁移过程可重复、结果可衡量。
AI 深度解读
把 PHP 应用迁到 Java,最容易误判的进度是「能编译、能启动,迁移就差不多了」。成熟项目里的业务约束可能藏在 Eloquent trait、字段可见性和 ORM XML 映射里,结构相似的 Java 代码,行为仍可能不同。
AWS ML Blog 这篇文章提出,用 Kiro 把迁移做成可重复的工程流程:先扫描旧系统,再建立行为校验,最后按共享规则生成代码。思路值得借鉴,但要先记住一个限制:文中的样例只迁了 37 个模型中的 4 个,而且没有建成它最强调的行为校验工具。
为什么扫描必须排在 AI 翻译前面
作者把旧 PHP 应用当作迁移规格,因为积累多年的系统,往往只有代码完整记录了真实行为。Laravel、Symfony、Doctrine 的约定又会把这些行为分散到不同位置,逐个打开实体文件,并不一定能看全。
因此,流程的第一条硬规则是:扫描器运行之前,不读、猜测或手工翻译模型与实体文件。
扫描器 discover-models.php 是一个单文件、无依赖的 PHP 命令行工具,需要 PHP 8.0 或更新版本。它只把源码读取为 token,不执行目标代码,也不要求先装好目标应用的依赖。这降低了旧项目环境难以恢复时的摸底成本,但它也因此只能发现静态源码能表达的信息。
每次扫描都运行三种发现策略:
- 沿继承链寻找
Illuminate\Database\Eloquent\Model,识别 Eloquent 模型。 - 检测 Doctrine 的
#[ORM\Entity]属性。 - 读取外部
*.orm.xml映射文件。
结果统一进入 JSON 清单。models[] 保存字段、类型转换、关系和可见性规则,每个条目都带有 flags[]。遇到运行时表达式生成的 $fillable,扫描器不会猜结果,而是留下自然语言说明,交给人处理。
这个设计的价值不只是让 AI 少漏几个字段。它把「已确认的结构」与「仍待判断的问题」分开了。后续生成 Java 时,团队可以追溯某个映射来自哪里,也能知道哪些地方尚未获得可靠依据。
静态扫描并没有消灭不确定性,而是把它变成可审查的队列。
先证明验收工具有效,再让 AI 批量迁移
文章反复强调行为一致性校验工具,即 parity harness。它会把请求与响应样本用于 PHP 原系统和 Java 迁移版本,检查两边的外部行为是否一致。
验收工具要在 Java 代码生成之前建立,并且必须能识别人为注入的错误。
只验证工具在正常 PHP 上通过还不够。作者要求故意破坏原系统,再确认校验失败。否则,一套总是亮绿灯的测试,可能只是没有检查到真正重要的行为。
流程名称叫「八阶段」,实际编号为 Phase 0–8:Phase 0 是准备阶段,后面才是八个正式阶段。
Phase 0 运行扫描器并整理清单。Phase 1 建立行为校验。Phase 2 生成迁移规则 RULEBOOK.md 和差距清单 GAP_INVENTORY.md。Phase 3 选择有代表性的文件试迁移,检验规则能否应对真实代码,再决定是否推广到整个应用。
这几步需要集中投入人的判断。越晚发现规则有误,返工范围越大。
Phase 4–8 才进入以自动循环为主的工作:搭建项目骨架,从清单生成数据模型,把路由转换为 controller、中间件转换为 filter、校验转换为带注解的数据传输对象,再分批迁移业务逻辑,最终通过行为校验并切换系统。每个差异都必须被修复,或者记录为经过批准的行为变更。
另一条关键原则是:发现重复错误,要修改规则并重新生成,而不是逐个修补输出。
例如,多处字段序列化都错了,手工改 Java 可以救下当前几个文件,却无法保证下一批生成结果正确。把原因补进规则,收益才能延续到后面的项目。不过,这要求团队明确哪些代码归生成流程管理,否则重新生成也可能覆盖人工维护的内容。原文没有展开这部分边界。
共享规则能复用,但样例还没证明完整迁移
这套引擎把方法论与项目分开。仓库根目录的 .kiro/ 放共享能力:php-model-discovery 负责扫描流程,php-to-java-migration 负责迁移流程,core-workflow.md 是 Steering 文件。各项目分别保存 PHP 源码、Java 输出,以及 .kiro/specs/ 下的规格。
同一套文件有两种执行方式。Kiro 在编辑器里逐步推进,一次处理一个应用,开发者审核发现清单、规则和阶段结果。AWS Transform 则通过与 Kiro 的集成,读取相同的 skill 文件,以并行任务处理多个应用,并在规则指定的检查点接受审查。文中的例子全部使用 Kiro。
可复用的核心是规则文件。某次迁移补充了映射规则,后面的项目和另一条执行路径就能继承它。
但样例的完成度必须单独看。laravel-eloquent-sample 只覆盖一个开源 Laravel 应用的只读切片,迁移了 Book、Chapter、Page、User,目标环境是 Spring Boot 3.4.1、Java 21、Maven 和内存 H2 数据库。
其中的映射很直观:PHP namespace 对应 Java package,Eloquent 模型对应 JPA @Entity,hasMany、belongsTo 对应 @OneToMany、@ManyToOne,查询 scope 对应 Spring Data repository 方法。
更能说明问题的是序列化:Page 的 $hidden 包含 html、markdown、text,所以生成代码给它们加上 @JsonIgnore;Book 的 description 则刻意保留。这类细节即使迁错,项目也可能照样编译通过。
然而,样例只迁了 37 个模型中的 4 个,规格还承认 parity harness 从未建成,并称其为「最大的缺口」。因此,它展示了结构映射和流程组织,尚未证明端到端行为一致。
我的判断
我认可这篇文章把验收前置,也认可用清单与规则约束 AI。相比直接让模型「把整个 PHP 项目改成 Java」,这种做法更容易定位遗漏、复查决策,并积累可复用的迁移知识。
但文章最有价值的是方法设计,证据还不足以支持大规模迁移效果的结论。
作者没有给迁移耗时、人工修正量、缺陷率,也没有与人工重写或其他转换方式做对照。AWS Transform 的并行执行是文中描述的运行路径,不能据此推算吞吐或成本收益。
行为校验也有前提。请求与响应对比能覆盖多少,取决于样本和断言质量。文中没有交代数据库副作用、事务、异步任务、权限与异常路径怎样验证;只读样例也无法替这些场景作答。原文开头提到 Java 的类型安全、库支持和扩展能力,这些是迁移动机,文中没有实测它们带来的收益。
一般团队还可能遇到基线难以运行的问题。扫描器不执行旧应用,确实方便摸底;但要建立可信的行为校验,仍需恢复可运行的 PHP 环境、数据和依赖。扫描能启动,不代表验收条件已经具备。
「修改规则再生成」适合重复出现、能归纳的错误。独特业务逻辑是否值得抽象成共享规则,则需要判断。文章给出的是工程方向,不是一条能替代所有人工修复的定律。
能拿来做什么
- 接手 PHP 后端迁移时,先整理模型、关系、隐藏字段和歧义清单,把尚未确认的规则显式列出来,再安排 AI 分批转换。
- 前后端联调前,优先保留现有接口的请求与响应样本,检查字段缺失、可见性和错误返回;再故意改坏一处行为,确认校验能报错。
- 让 AI 批量生成代码时,把跨文件重复出现的问题回写到迁移规则,并用代表性文件重新验证,避免把同一种错误带进下一批输出。
- 试用这套引擎时,从边界清楚的只读模块开始,按 README 固定上游提交,将「生成成功」和「行为验证通过」分别记录,再决定是否扩大范围。