跳到正文
AWS Machine Learning Blog· Sarat Guttikonda·· 4 天前AI 评分38

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

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

AI 导读

Kiro 提供了一套可重复的 PHP 到 Java 迁移引擎,把原 PHP 应用当作规格说明,在一致性校验通过前不判定 Java 移植版正确。

摘要与补充说明

该引擎由共享方法论、机械式发现扫描器和八阶段工作流组成,全部打包为版本化的 Markdown 技能文件(php-to-java-migration 与 php-model-discovery),因此同一套方法既能在 Kiro 中以交互方式逐个应用运行,也能交给 AWS Transform 以智能体方式并行处理多个应用。核心规则是先发现后翻译:扫描器单遍运行、无依赖,对源码 token 应用三种发现策略并输出一份 JSON manifest,歧义项进入人工复核队列。

正文· 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 模型已迁移到 Spring Boot 3.4.1、Java 21、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:左侧为清单驱动的映射。右侧为生成的应用切片的层化运行时架构

这些映射是机械化的,并且可以追溯到 manifest:PHP 命名空间变成 Java 包,Eloquent 模型变成 JPA @Entity,has Many 和 belongs to 关系变成 @OneToMany 和 @ManyToOne,Eloquent 查询作用域变成 Spring Data 仓库方法。这种纪律体现在序列化上:html、markdown 和 text 带有 @JsonIgnore,因为 manifest 将它们记录在 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 manifest 文件。如果你不打算引用它,请从工作目录中删除发现扫描器的 JSON manifest。
  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阅读原文

相关阅读

专题与标签

相关资讯专题