TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

4.5 KiB

AOT 与 PHP 不兼容特性清单

本文档只记录当前 AOT 编译器与标准 PHP 不兼容或受限的关键特性。

程序结构

  • 全局作用域不允许可执行语句;只允许声明、usedeclare、常量定义等静态结构。
  • 函数和方法内部不允许声明函数。
  • 函数和方法内部不允许声明具名类。
  • 二进制模式必须定义全局 main()
  • main() 只允许无参数,或 (int $argc, array $argv)
  • main() 必须返回 void

声明与类型

  • 不支持可变变量 $$var
  • PHP 8.4 property hooks 会降级为 AOT getter/setter;直接属性读写和动态对象读写均受支持。当前不支持对 hook 属性取引用。
  • 支持 private(set)protected(set) 非对称属性可见性;在 PHP 8.2~8.4 后端通过自定义属性写 handler 执行同等作用域检查。
  • 不支持闭包或箭头函数按引用返回。
  • __construct() 不允许返回值。
  • 参数默认值不允许出现在必填参数之前(PHP允许,但会直接丢弃此默认参数)。
  • 不支持引用可变参数 &...$args
  • 联合类型、交叉类型、nullable 类型仍以 mixed/any 作为 C++ 表示,但静态阶段会利用已知表达式类型提前拒绝确定不兼容的参数、返回值和属性赋值;动态值仍保留运行时 type check。
  • 局部变量类型一旦被静态推断为具体 native 类型,不支持在同一作用域内重新赋值为不兼容类型。
  • attribute 参数不支持非空数组值和 new 表达式。

declare

  • 不支持 declare(ticks=...)
  • declare(encoding=...) 只允许 UTF-8
  • declare(strict_types=...) 只允许 strict_types=1
  • 不支持其他 declare 指令。

调用与引用

  • TypePHP 使用严格参数数量规则:非 variadic 函数不接受声明范围之外的额外参数;func_get_args() 不会隐式放宽签名。
  • 闭包和箭头函数不支持引用参数。
  • 引用赋值不支持从复杂静态属性表达式建立引用。
  • 动态调用、闭包调用等编译期无法确定参数签名的调用,不能自动转换引用参数;需要显式使用 refval() 或等价关键词方法 toRef()
  • refval() / toRef() 只接受变量、数组元素或对象属性。
  • 带 unpack 且尾部追加 named arguments 的调用会退化为动态调用,不能使用 native call。

对象模型

  • toInt()toString()toArray() 等保留关键词方法先于普通对象方法解析;需要参数的同名业务方法不按普通对象方法语义调用。
  • 固定值类型属性未显式初始化时使用类型零值,不保留 ZendPHP 的完整 uninitialized 状态;因此 ?? 等依赖 uninitialized 状态的表达式可能不同。
  • 禁止子类用同名 private 属性隐藏父类私有属性;public / protected 同名声明视为同一个继承 property slot,仍须满足类型、可见性和 readonly 兼容性要求。
  • 为避免 typed property 写入路径引入额外动态检查,native typed property 在右值类型不确定或与属性类型不一致时会退化为 setProperty();部分标量赋值可能遵循 Zend 弱类型转换,而不是 AOT 默认 strict 语义。
  • constructor property promotion 的运行时属性可用,但 ReflectionProperty::isPromoted() 目前不返回标准 PHP 结果。

表达式与控制流

  • match 的 arm condition 不能是 match 表达式。
  • foreach by reference 的 value 只能是变量。
  • foreach by reference 不支持 list destructuring。
  • 固定 native typed object property 不允许按 PHP 未初始化语义自由 unset()
  • native 类型变量执行 unset() 不会产生标准 PHP 的变量删除语义。

运行时动态能力

  • ClassName::class 只支持字符串字面量或可静态解析的类名。
  • static::class 在需要编译期常量类名的位置不支持。
  • __CLASS__ 只允许在 class 定义的代码段中使用(PHP允许,返回空字符串)。
  • __TRAIT__ 只允许在 trait 定义的代码段中使用(PHP允许,返回空字符串)。
  • 动态属性链、动态类名、动态函数名和动态回调会统一走 Zend runtime fallback,不保证 native 优化;动态调用的引用参数仍需显式使用 refval()toRef()
  • Closure::bind() 绑定静态闭包访问私有成员时,当前行为与标准 PHP 不完全一致。
  • first-class callable 存入 typed nullable Closure 属性后,当前存在运行时稳定性限制。
  • 所有源文件必须是 UTF-8 编码。