AWS Machine Learning Blog

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

6.9内容质量
Build a repeatable PHP-to-Java migration engine with Kiro

TL;DR · AI 摘要

Build a repeatable PHP-to-Java migration engine with Kiro Artificial Intelligence Build a repeatable PHP-to-Java migrati...

核心要点

  • 主题聚焦:Build a repeatable PHP-to-Java migration engine
  • 来源:AWS Machine Learning Blog,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#后端#云计算#安全
打开原文

使用 Kiro 构建可重复的 PHP 到 Java 迁移引擎 | 人工智能

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

当团队将成熟的 PHP 应用迁移到 Java 时,可以获得更强的类型安全性、更广泛的库支持以及更可预测的扩展性。经过多年使用 Laravel、Symfony 或 Doctrine 构建的 PHP 代码库,其业务规则可能隐藏在非显眼的位置(从 Eloquent trait 到 XML 映射文件),因此结构相似的 Java 移植版本虽然能编译通过,但行为可能不同。

本文将展示如何通过 Kiro 将 PHP 到 Java 的迁移从一次性的信任飞跃转变为可衡量、可重复的过程。Kiro 是一个集成人工智能的开发环境(IDE),它通过将人工智能代理与代码库配对,与您协同完成多步骤的工程任务。该方法的核心是一个可复用的引擎:共享方法论、机械发现扫描器和八阶段工作流程。该引擎将原始 PHP 应用视为规范,直到一致性测试套件验证 Java 移植版本正确性之前,不会确认 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 将人工智能代理引入您的编辑器,逐步引导迁移过程。将仓库根目录作为 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 输出和规范子文件夹。

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

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

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

.kiro/ 下的共享全局层包含两个技能:php-model-discovery(扫描器)和 php-to-java-migration(八阶段操作手册),以及核心指导文件 core-workflow.md。每个项目文件夹下均包含自己的 PHP 源代码、Java 输出和规范子文件夹(位于 .kiro/specs/ 下),因此改进方法论后,所有项目均可继承该改进。

翻译前的发现阶段

最重要的规则在任何操作之前生效:在扫描器运行完成前,不要阅读、猜测或手动翻译模型或实体文件。

如下图所示,扫描器以单次遍历方式运行且无依赖项。它对源代码标记应用三种发现策略,并生成一个 JSON 清单,所有歧义内容会进入人工审核队列等待解决。

图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在全应用部署前对代表性文件进行压力测试。

图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 构造,从而生成生成的应用程序切片的分层运行时架构。

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

这些映射是机械的,并且可以追溯到清单:PHP 命名空间变为 Java 包,Eloquent 模型变为 JPA @Entity,has Many 和 belongs to 关系变为 @OneToMany 和 @ManyToOne,Eloquent 查询作用域变为 Spring Data 仓库方法。在序列化方面也体现了规范:html、markdown 和 text 因为清单记录在 Page 的 $hidden 列表中而携带 @JsonIgnore,而 Book 的描述则故意没有。

该规范明确指出只有 37 个模型中的 4 个被迁移,并且更重要的是,这个切片从未构建过 parity harness,它称之为“最大的差距”。记录其不足之处本身就是设计的一部分。

入门

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

使用方法:

  • 克隆仓库并将根目录作为 Kiro 工作区打开(打开文件夹并选择包含 .kiro/ 的文件夹)。除了为扫描器需要的 PHP 8.0+ 和 Java 21 与 Maven 外,无需安装其他内容。
  • 将 PHP 源代码获取到项目 source-php/ 文件夹中。README 中指定了用于 parity 的确切上游提交,任何人都可以重现基准线。
  • 要求 Kiro 迁移应用程序。php-to-java-migration 技能会自动激活,首先运行扫描器,在 .kiro/specs/ 下生成新的规范,并引导您完成审批关卡。
  • 对于代理运行,将 AWS Transform 指向相同的技能文件,使其代理在您的投资组合中执行相同的方法论。

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

清理

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

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

结论

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

  • 翻译前的发现:机械扫描器会清点每个模型、字段和关系,因此您无需猜测结构。
  • 在编写第一行 Java 代码之前先构建判断标准:parity harness 在开始之前就定义了完成的标准。
  • 修复循环而非代码:当多个文件中出现相同错误时,应修改规则书并重新生成,而非手动修补。
  • 共享统一的方法论:该方法论只需编写一次,可跨项目共享,并随着每次迁移持续优化。

这些原则并不局限于 PHP 或 Java。其他类型的迁移同样适用这一模式,特别是当旧系统是唯一完整规范时。克隆示例 PHP-to-Java 迁移仓库,将其作为 Kiro 工作区打开,探索驱动该迁移的 Skills 和 Steering 功能,或直接将相同的技能文件应用于 AWS Transform。如需了解 AWS 上的语言迁移模式,请参阅 AWS Prescriptive Guidance 文档。

About the authors

'"`