Skip to content

feat: add SaiAdmin Linux AOT profile - #1

Open
supdger wants to merge 2 commits into
Tinywan:mainfrom
supdger:feat/saiadmin-aot-profile
Open

supdger wants to merge 2 commits into
Tinywan:mainfrom
supdger:feat/saiadmin-aot-profile

Conversation

@supdger

@supdger supdger commented Sep 14, 2026

Copy link
Copy Markdown

背景

SaiAdmin 及其随附依赖包含一批 TypePHP v0.8 当前无法直接编译或运行的动态写法。这个 PR 复用现有 doctor、Docker builder、TypePHP 编译和 portable-dir 打包链,增加一个失败关闭的 SaiAdmin Linux amd64 profile,不另建编译器或同功能插件。

使用方式

php webman typephp:doctor
php webman typephp:package --profile=saiadmin

主要改动

  • 自动发现 SaiAdmin 核心、appsupport 和所有 plugin/*/app 服务端业务 PHP。
  • .typephp/build/ 生成版本和源码结构受约束的兼容副本,不修改普通 PHP 源码或项目 vendor。
  • 为每条规则校验依赖版本、源码 reference 和预期命中数量;版本漂移、未命中或重复命中立即失败。
  • 生成逐文件 source-coverage.json,阻止业务 PHP 漏编译、静默排除或泄漏进 portable-dir。
  • 修复实际复现的 Webman、Workerman、ThinkORM、Carbon、SaiAdmin 与 TypePHP v0.8 兼容缺口。
  • 增加开发规范、迁移指南、支持矩阵、配置样例、中立插件及产物/业务验收脚本。

验证

  • Pest:128 passed,1,369 assertions(1 个既有 fixture warning)
  • PHP 8.4 syntax:通过
  • Shell syntax 与 git diff --check:通过
  • Linux amd64 完整编译/链接:2,283 / 2,283
  • SaiAdmin 业务源码覆盖:142 / 142(131 直接编译,11 由等价 AOT 副本替代)
  • portable-dir、ELF x86-64、动态库、运行资源、manifest、coverage hash 与业务源码泄漏检查:通过
  • 隔离环境:验证码、登录、用户信息、权限拒绝和中立插件路由通过
  • 普通 PHP 对照:相同业务路径通过

当前边界

  • 首版仅支持 Linux amd64/glibc 和文档中锁定的 SaiAdmin 6.1.1 依赖组合。
  • 未知插件或依赖版本漂移会停止构建,不会静默丢失功能。
  • Windows exe/DLL 不在本 PR 范围。

@supdger

supdger commented Sep 15, 2026

Copy link
Copy Markdown
Author

已补充脱敏的 Linux amd64 AOT 实跑证据,包含锁定版本、完整编译数量、ELF/动态库/coverage 校验、三组产物 SHA-256、Workerman 启动记录、验证码/登录/用户信息/权限拒绝/中立插件路径,以及普通 PHP 对照和复现命令:

https://github.com/supdger/webman-typephp/blob/feat/saiadmin-aot-profile/docs/saiadmin-aot/docs/verification-evidence.md

Tinywan pushed a commit that referenced this pull request Sep 17, 2026
TypePHP 编译产物以严格类型模式调用内置函数,实参不再经 coercive 模式做
__toString 宽松转换,而 webman `Config::loadFromDir()` 与 `Route::load()`
把 RecursiveDirectoryIterator 产出的 SplFileInfo 直接交给 is_dir()/substr()/
pathinfo()/include,编译后启动即抛
`is_dir(): Argument #1 ($filename) must be of type string, SplFileInfo given`。

新增 STRINGABLE_ARG_SOURCES 与 generateStringableArgSources(),把这些迭代器
实参统一改写为 `$file->getPathname()` 并忽略 vendor 原版,取值语义不变。
需要按缩进消歧的同名语句只在行首 \n 锚定:行尾锚定在 CRLF 源上永不命中
(分号与 \n 之间还夹着 \r),LF/CRLF 两种行尾因此都能命中。PackageCommand
同步登记 stringable-arg 分组,补丁产物写入 build-manifest.json 的
stringable_arg_hashes。补充单元测试覆盖五处改写点,并断言 read() 与
loadAnnotationRoutes() 中同名不同缩进的字符串实参不被误伤。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant