yangweijie / aot-rector
Rector rules for transforming PHP code to be compatible with Swoole AOT Compiler
Package info
github.com/yangweijie/aot-rector
Type:rector-extension
pkg:composer/yangweijie/aot-rector
v0.1.0
2026-05-18 02:32 UTC
Requires
- php: >=8.1
- rector/rector: ^2.0
Requires (Dev)
- pestphp/pest: ^3.0
README
将 vendor 目录中的第三方 PHP 代码转换为兼容 Swoole AOT Compiler 语法的自动化工具。
工作原理
composer aot:rector
│
├── Step 1: Rector 转换
│ vendor/bin/rector process vendor/ → @aot/
│ (应用 6 条规则,83+ 个文件被转换)
│
├── Step 2: 生成补丁
│ vendor/bin/aot-patch → patches/*.patch
│ (对比 vendor 和 @aot,生成 diff)
│
└── Step 3: 应用补丁
aot-patch → 将 @aot 文件复制回 vendor/
(修改后的 vendor 代码即可用于 AOT 编译)
规则列表
| 规则 | 针对语法 | 操作 |
|---|---|---|
DollarDollarToArrayAccessRector |
$$var 动态变量 |
转为 $_dyn_vars[$key] |
ExtractToManualAssignmentRector |
extract() 函数 |
替换为参数表达式 + 注释提醒 |
MultiBreakContinueRector |
break N / continue N |
添加注释提醒改用 goto |
StringNullByteRector |
字符串字面量中含 \0 |
替换为 "str".chr(0)."续" |
FreeCodeToFunctionRector |
游离代码(不在函数内) | 标记检测结果 |
ClosureRefParamToRefvalRector |
闭包引用参数 &$var |
添加注释提醒使用 refval() |
安装
composer require yangweijie/aot-rector
配置
1. rector.php
复制模板到项目根目录:
cp vendor/yangweijie/aot-rector/rector.php.dist rector.php
根据项目的 vendor 依赖,在 withSkip 中添加需要跳过的文件:
->withSkip([ // ... 默认跳过规则 ... 'vendor/topthink/framework/src/think/exception/Handle.php', 'vendor/topthink/think-helper/src/helper/Arr.php', // 你的项目中解析报错的文件 ])
2. composer.json 脚本
Composer 脚本不会自动从依赖包继承,需要在根项目的 composer.json 中添加:
"scripts": { "aot:rector": [ "vendor/bin/rector process vendor/ --config rector.php", "vendor/bin/aot-patch" ], "aot:rector-dry": "vendor/bin/rector process vendor/ --config rector.php --dry-run || true", "aot:patch": "vendor/bin/aot-patch" }
命令参考
| 命令 | 说明 |
|---|---|
composer aot:rector |
完整流程:Rector 转换 → 生成补丁 → 应用到 vendor |
composer aot:rector-dry |
预览:只显示 Rector 会改哪些文件,不改写 |
vendor/bin/aot-patch |
仅补丁:对比 @aot/ 和 vendor/,生成补丁并应用 |
composer aot:patch |
同上(通过 composer 脚本) |
首次运行:
# 先预览 composer aot:rector-dry # 确认后执行 composer aot:rector
后续如果修改了 patches/ 中的补丁文件,重新执行 composer aot:rector 或 vendor/bin/aot-patch 即可同步到 vendor。
目录说明
项目根目录/
├── rector.php # Rector 配置文件(需手动创建)
├── @aot/ # Rector 转换后的代码(自动生成)
│ └── vendor/ # — 镜像 vendor 目录结构
├── patches/ # 补丁文件(自动生成,可手动修改)
│ └── .manifest.json # — 已补丁文件清单
└── vendor/ # 被修改的 vendor 代码
跳过规则配置
rector.php 中 withSkip 的常见配置项:
->withSkip([ // 测试文件 '*/Tests/*', '*/tests/*', '*/Test/*', '*/test/*', // Composer 自动生成文件 '*/vendor/autoload.php', '*/vendor/composer/*', // Rector 自身(避免嵌套 vendor/ 循环) 'vendor/rector/**', // Rector 解析器不支持的语法 'vendor/symfony/polyfill-*/**', 'vendor/symfony/var-dumper/**', // 项目中解析报错的特定文件 'vendor/topthink/framework/src/think/exception/Handle.php', 'vendor/topthink/framework/src/think/view/driver/Php.php', 'vendor/topthink/think-helper/src/helper/Arr.php', // 非 PHP 文件 '*.json', '*.yml', '*.yaml', '*.xml', '*.neon', '*.md', '*.dist', ])
注意:被跳过的文件不会被 Rector 转换,但不影响 AOT 编译。AOT 编译器使用 ZendPHP 自己的解析器而非 Rector 的
nikic/php-parser。
开发
运行测试
cd packages/aot-rector composer install composer test
测试夹具结构
tests/Rules/Fixtures/{RuleName}/
├── some_feature.php.inc # 转换测试
├── skip_passthrough.php.inc # 不做转换的测试(无 ----- 分隔符)
└── ...
夹具格式:
<?php // ———— 输入(转换前) ———— $name = 'foo'; $$name = 'hello'; ?> ----- <?php // ———— 期望输出(转换后) ———— $name = 'foo'; $_dyn_vars[$name] = 'hello'; ?>
Patcher 类
Aot\Rector\Patcher— 补丁生成和应用Aot\Rector\PatcherConfig— 路径配置常量bin/aot-patch— CLI 入口(Composer bin 脚本)
路径解析使用 getcwd() 获取项目根目录,因此可以在任意目录执行。