跳到正文
AWS Machine Learning Blog· Sarat Guttikonda·· 2 小时前AI 评分38

用 Kiro 构建可重复的 PHP 到 Java 迁移引擎

Build a repeatable PHP-to-Java migration engine with Kiro

AI 导读

Kiro 提供一套可重复的 PHP 到 Java 迁移引擎,把原 PHP 应用当作规格说明,通过共享方法论、机械式发现扫描器和八阶段工作流,在一致性校验通过前不判定 Java 移植正确。同一套 skill 文件既可在 Kiro 中交互式逐应用运行,也可交给 AWS Transform 以智能体方式并行处理多个应用,输出经一致性验证的 Spring Boot Java。

正文 · AI 翻译

当你的团队将成熟的 PHP 应用迁移到 Java 时,你会获得更强的类型安全性、更广泛的库支持以及更可预测的扩展能力。多年来用 Laravel、Symfony 或 Doctrine 构建的 PHP 代码库,其业务规则散落在一些并不显眼的地方,从 Eloquent trait 到 XML 映射文件,因此一个结构相似的 Java 移植版本可能编译干净通过,但行为仍然不同。

本文展示如何利用 Kiro 将 PHP 到 Java 的迁移从一次性的盲目冒险转变为可度量、可重复的过程。Kiro 是一个 AI 集成开发环境(IDE),它将 AI 代理与你的代码库配对,在你参与循环的情况下执行多步骤工程任务。该方法的核心是一个可复用的引擎:共享方法论、机械式发现扫描器以及八阶段工作流。该引擎将原始 PHP 应用视为规范,在一致性测试框架验证通过之前,拒绝宣布 Java 移植版本正确。

前提条件

开始之前,你需要:

  • 熟悉 PHP(Laravel/Eloquent 或 Symfony/Doctrine)。了解 Java(Spring Boot、JPA)有助于你审查生成的输出,但引擎会为你生成地道的 Java 代码,因此你不需要自己用 Java 重写应用。
  • 一个可访问 Skills 和 Steering 文件的 Kiro 工作区。
  • 运行发现扫描器的机器上安装 PHP 8.0 或更新版本,以及用于生成的 Spring Boot 项目的 Java 21 和 Maven。
  • 对迁移规划(发现、翻译和验证)有基本了解。

本文你将学到什么

你从一个开放的代码仓库开始,因此可以自己运行引擎,而不是仅仅阅读相关内容。引擎所知的一切都存在于一小组技能文件中,借助这些文件,你可以用不止一种方式运行相同的方法论。

运行引擎的两种方式:Kiro 和 AWS Transform

这里的一切都打包为技能文件:版本化的 Markdown 能力包,编码了迁移方法论(php-to-java-migration)和发现扫描器工作流(php-model-discovery)。由于这些知识存在于文件中而非任何单一工具中,你可以用两种方式运行相同的方法论。

方法 1:Kiro,交互式且开发者参与循环

Kiro 将 AI 代理带入你的编辑器,逐步驱动迁移。将仓库根目录作为 Kiro 工作区打开,当你要求 Kiro 迁移 PHP 应用时,技能会自动激活。然后 Kiro 会走完八阶段工作流,并设有明确的审批关卡,因此你可以审查发现清单、批准规则手册,并在下一阶段开始前签署确认每个阶段。本文中的每个示例都使用此模式。

方法 2:AWS Transform,代理式且面向组合规模

AWS Transform 是 AWS 用于大规模迁移和现代化的代理式 AI 服务,它现在与 Kiro 原生集成。通过该集成,你可以将管理交互式 Kiro 会话的相同技能文件交给 AWS Transform,因此翻译前的发现、作为裁判的一致性测试框架以及“修复循环,而非代码”都适用于自主运行。

每种路径的适用场景

  • 控制与自主性: 先使用 Kiro 处理代码:在一个应用上运行技能,阅读生成的 Java 代码,并运行测试。当你想要迁移更多内容时,AWS Transform 会以代理方式运行相同的方法论,并在技能定义的检查点进行审查。
  • 规模与新颖性:Kiro 一次处理一个应用,适合首次出现的框架。AWS Transform 以并行作业方式运行多个应用。
  • 共享反馈循环:两条路径读取相同的技能文件,因此在 Kiro 中做出的每一处规则手册修正都会改进下一次 AWS Transform 运行,反之亦然。

解决方案概述:一个共享大脑,多个项目

该引擎围绕一个原则组织:一个共享大脑,多个项目。要打开它,请在本地克隆仓库,然后在 Kiro 中打开一个文件夹并选择仓库根目录(包含 .kiro/ 的文件夹)。Kiro 会自动加载技能和引导文件,更完整的步骤见“入门”。

工作区将共享方法论层与使用它的各个项目分开,如下图所示。顶部是每个项目都会使用的全局 .kiro/ 层。其下是各项目文件夹,每个文件夹都有自己的 PHP 源代码、Java 输出和规范子文件夹。

Workspace architecture: one shared brain, many projects. Diagram of the workspace layout. At the top is the Kiro workspace root, PHP-Java-Migration. Below it, a shared, global layer under .kiro/ holds the skills (the methodology) and the steering file (the governing workflow), and applies to every project. Beneath that, three per-project folders each hold their own spec sub-folder, and the diagram notes that improving the shared layer once benefits every project.

图 1:工作区分为共享的全局方法论层和各项目的代码与规范文件夹

这些相同的共享技能文件可以通过两种不同方式运行,如下图所示。相同的八阶段、一致性优先流水线既可以由 Kiro 驱动(交互式,一次一个应用),也可以由 AWS Transform 驱动(智能体式,组合规模),两者都将 PHP 源代码转换为经过一致性验证的 Spring Boot Java。

PHP-to-Java Migration Engine: One Shared Brain, Two Execution Paths. Overview of the migration engine. A shared layer on the left holds the skill files and steering file that every project uses. Two execution paths on the right run the same methodology: Kiro, for interactive work on one application at a time, and AWS Transform, for agentic work across a portfolio. Below them, an eight-phase pipeline runs from the PHP codebase through Phases 0 to 3 (human judgment), then Phases 4 to 8 (self-driving loops), and ends at a parity harness that acts as the referee.

图 2:相同的共享技能文件驱动两条执行路径:Kiro(交互式,一次一个应用)和 AWS Transform(智能体式,组合规模)。两者都运行相同的八阶段一致性优先流水线,将 PHP 源代码转换为经过一致性验证的 Spring Boot Java

在 .kiro/ 下有一个共享的全局层,包含两个技能:php-model-discovery(扫描器)和 php-to-java-migration(八阶段操作手册),以及 core-workflow.md 引导文件。每个项目文件夹在 .kiro/specs/ 下都有自己的 PHP 源代码、Java 输出和规范子文件夹,因此改进一次方法论就能让每个项目继承这一收益。

先发现,后翻译

最重要的规则先于一切生效:在扫描器运行之前,不要读取、猜测或手工翻译模型或实体文件。

扫描器以单次遍历、无依赖的方式工作,如下图所示。它对源令牌应用三种发现策略,并输出一个 JSON 清单,任何有歧义的内容都会被路由到审查标记队列,由人工解决。

php-model-discovery, three strategies, one manifest. Diagram of the discovery scanner, discover-models.php. On the left, the PHP codebase feeds into the scanner, which runs three strategies in sequence: Eloquent model discovery, Doctrine attribute detection, and ORM XML mapping. An arrow then carries the results to model-manifest.json on the right, which holds a models array of fields, casts, and relationships, plus a flags array that serves as the human review queue.

图 3:扫描器对源令牌运行三种发现策略,并输出一个带有审查标记队列的 JSON 清单

扫描器是 discover-models.php,一个单文件、无依赖的 PHP 命令行工具,不执行目标代码。它只将源文本作为令牌读取,因此无论依赖是否安装,它都能针对你选择的应用运行。它在每次扫描时运行三种策略:Eloquent 模型发现(沿类继承链走到 Illuminate\Database\Eloquent\Model)、Doctrine 属性检测(#[ORM\Entity] 属性)和 ORM XML 映射(外部 *.orm.xml 文件)。输出是一个 JSON 清单。一个 models[] 数组携带每个字段、类型转换、关系和可见性规则,每个条目上都会出现一个 flags[] 数组。扫描器会标记歧义而不是猜测。例如,由运行时表达式构建的 $fillable 列表会变成一条通俗英语的标记,而该标记列表就是人工审查队列。

一致性优先流水线

阶段 0 是准备阶段:它运行扫描器并汇总清单。接下来的三个阶段则集中投入人力专业知识。阶段 1 在编写 Java 代码之前构建一致性校验工具,针对 PHP 原版和 Java 移植版重放请求/响应对。该工具必须在可正常工作的 PHP 上通过,并在你故意破坏它时失败,因为一个漏掉注入式破坏的校验工具是不可信的。阶段 2 播种规则手册和差距清单(RULEBOOK.md、GAP_INVENTORY.md),阶段 3 在将其推广到整个应用之前,用代表性文件对其进行压力测试。

The parity-first migration pipeline (8 phases) Diagram of the parity-first migration pipeline with eight phases. Phases 0 to 3 are the human-led judgment steps, and Phases 4 to 8 are self-driving loops, and both groups feed a parity harness that acts as the referee comparing the PHP original with the Java port.

图 4:人的判断被前置到准备阶段 0 和阶段 1–3。阶段 4–8 主要是自驱动的循环,由一致性校验工具担任裁判

前四个阶段集中投入人力专业知识。阶段 0 运行扫描器并汇总清单。阶段 1 在编写 Java 代码之前构建一致性校验工具,针对 PHP 原版和 Java 移植版重放请求/响应对。该工具必须在可正常工作的 PHP 上通过,并在你故意破坏它时失败,因为一个漏掉注入式破坏的校验工具是不可信的。阶段 2 播种规则手册和差距清单(RULEBOOK.md、GAP_INVENTORY.md),阶段 3 在将其推广到整个应用之前,用代表性文件对其进行压力测试。

阶段 名称 交付物
0 评估与发现 模型清单 + 清单 + 切换选择
1 构建裁判 可针对 PHP 和 Java 运行的一致性校验工具
2 规则手册 + 差距清单 RULEBOOK.md、GAP_INVENTORY.md
3 对规则手册进行压力测试 经过加固的规则手册,已用代表性文件验证
4 脚手架 可编译的 Spring Boot 项目
5 翻译数据模型 JPA 实体 + 模式基线
6 翻译 I/O 层 控制器、安全、模板可响应
7 转换业务逻辑 逻辑已转换,测试通过
8 证明一致性并切换 一致性报告 + 切换检查清单

阶段 4–8 主要是自驱动的循环:阶段 4 搭建项目脚手架,阶段 5 从清单翻译数据模型,阶段 6 翻译 I/O 层(路由变为控制器,中间件变为过滤器,校验变为带注解的数据传输对象),阶段 7 分批转换业务逻辑,阶段 8 用校验工具证明一致性并切换。两条原则支配着这个循环。第一,PHP 代码就是规范:当裁判认可时移植即完成,或者每个不匹配项都被记录为已批准的变更。第二,你修复的是循环,而不是代码,即修订规则手册并重新生成,而不是手工打补丁。

演练:从 Eloquent 到 Spring Boot

laravel-eloquent-sample 项目是一个可运行、有边界的示例:一个开源 Laravel 应用的只读切片,其中 Book、Chapter、Page 和 User 模型已迁移到基于 Java 21 的 Spring Boot 3.4.1,使用 Maven 和内存 H2 数据库。

从 PHP 到 Spring Boot 的映射是机械且可追溯的,如下图所示。左侧的每个清单条目映射到右侧的一个 Java 构造,从而生成应用切片的层次化运行时架构。

From Eloquent to Spring Boot: mapping and the generated slice. Diagram in two parts. The left side maps PHP and Laravel Eloquent constructs to their Java and Spring Boot equivalents, with arrows linking each pair, such as models to JPA entities and query scopes to Spring Data repository methods. The right side shows the layered architecture of the generated book-stack slice: an HTTP client calls a controller layer, which calls a repository layer, then an entity layer, and finally an H2 in-memory database.

图 5:左侧是清单驱动的映射。右侧是生成的应用切片的层次化运行时架构

这些映射是机械性的,并且可以追溯到清单:PHP 命名空间变成 Java 包,Eloquent 模型变成 JPA @Entity,has Many 和 belongs to 关系变成 @OneToMany 和 @ManyToOne,Eloquent 查询作用域变成 Spring Data 仓库方法。这种纪律体现在序列化上:html、markdown 和 text 带有 @JsonIgnore,因为清单将它们记录在 Page 的 $hidden 列表中,而 Book 的 description 则有意不这样做。

规范坦率地指出,37 个模型中只有 4 个被移植,而且最重要的是,针对这一部分从未构建过一致性测试框架,它称之为“最大的单一缺口”。记录其不足之处本身就是设计的一部分。

入门

完整的迁移引擎可在 示例 PHP 到 Java 迁移仓库 中获取。

要使用它:

  1. 克隆仓库并将其根目录作为你的 Kiro 工作区打开(打开文件夹并选择包含 .kiro/ 的文件夹)。除了用于扫描器的 PHP 8.0+ 和带有 Maven 的 Java 21 之外,无需安装任何东西。
  2. 将 PHP 源代码获取到项目的 source-php/ 文件夹中。README 固定了用于一致性对比的确切上游提交,以便任何人都能重现基线。
  3. 让 Kiro 迁移应用程序。php-to-java-migration 技能会自动激活,首先运行扫描器,在 .kiro/specs/ 下生成新的规范,并引导你完成审批关卡。
  4. 对于代理式运行,将 AWS Transform 指向相同的技能文件,这样其代理就能在你的整个组合中执行相同的方法论。

该方法论会自动检测 Laravel、Symfony、CodeIgniter 和纯 PHP,并且扩展是增量的:为新框架添加一行检测和一个 references/<framework>-to-spring.md 指南。由于 Kiro 和 AWS Transform 读取相同的文件,改进它们一次即可升级两个引擎。

清理

如果你在本演练过程中部署了示例 Spring Boot 应用程序:

  1. 停止正在运行的 Spring Boot 应用程序(内存中的 H2 数据库是临时的,无需单独清理)。
  2. 如果不再需要,从工作区中删除生成的 Java 项目文件夹。
  3. 发现扫描器只生成一个 JSON 清单文件。如果你不打算引用它,请从工作目录中删除发现扫描器的 JSON 清单。
  4. 迁移引擎本身不会预置任何 AWS 资源,因此没有需要取消预置的云资源。

结论

我们展示了如何使用 Kiro 构建一个可重复的 PHP 到 Java 迁移引擎,将大规模重写转变为可衡量、可累积的过程。关键原则是:

  • 先发现再翻译: 机械扫描器清点每个模型、字段和关系,因此你不必猜测结构。
  • 在代码之前构建评判器: 一致性测试框架在编写第一行 Java 之前就定义了完成。
  • 修复循环,而不是代码: 当同一个错误出现在多个文件中时,修改规则手册并重新生成,而不是手动修补。
  • 一个共享大脑: 方法论只编写一次,跨项目共享,并随着每次迁移而改进。

这些内容并非 PHP 或 Java 所特有。同样的形态也适用于其他迁移场景,即旧系统是唯一完整的规范。克隆 PHP 到 Java 迁移示例仓库,将其作为 Kiro 工作区打开,探索为其提供支持的 Skills 和 Steering 能力,或将相同的技能文件引入 AWS Transform。有关 AWS 上语言迁移模式的更多信息,请参阅 AWS Prescriptive Guidance 文档。


关于作者

Sarat Guttikonda

Sarat Guttikonda

Sarat 是 Amazon Web Services (AWS) 的首席解决方案架构师,与战略客户合作,大规模设计和交付云解决方案。他热衷于人工智能 (AI) 和机器学习 (ML),帮助客户在保持业务敏捷性的同时推动创新和转型。工作之余,Sarat 喜欢与儿子在 PS5 上玩合作游戏、旅行和打羽毛球。

Phani Parcha

Phani Parcha

Phani 是 Amazon Web Services 的高级技术客户经理(Strat),在构建和扩展企业平台方面拥有 22 年以上经验。他推动大规模企业工作负载的架构卓越性、系统可靠性和运营性能。Phani 专注于分布式系统、微服务架构和云原生平台,重点赋能企业转型和生成式 AI 解决方案。

Pallavi Jha

Pallavi Jha

Pallavi 是 Amazon Web Services 的技术顾问,通过 Kiro 和 AI 驱动的开发生命周期 (AIDLC) 帮助客户提升开发者生产力。她与企业合作实现工程实践现代化,专注于通过 AI 辅助、规范驱动的开发更快交付更高质量的软件。工作之余,她喜欢创作音乐和徒步。

来源:AWS Machine Learning Blog · aws.amazon.com