Skip to content
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
relied on the previous unconditional by-name behavior must pass the flag.
Closures declared in constant expressions are unaffected.

- Const-expr closures are referenced as `[class, "<site>@<rank>", line]` on
every PHP version: the id names the declaring reflection element (the class,
a constant, a property, a property hook or a method, parameters folded into
their method) and the closure's rank among the element's closures, in
evaluation order (attribute arguments first, nested const-expr surfaces
depth-first, then parameter defaults, then the constant or property default
value). The id equals the engine's own `getConstExprId()` for the sites the
engine addresses, and payloads produced on PHP 8.5, on PHP 8.6 and by the
polyfill are identical. On PHP 8.6 encoding uses the engine's non-evaluating
walk for anonymous closures and decoding tries `Closure::fromConstExpr()`
first, falling back to the evaluating walk (which alone covers constant and
property-default values). The previous site-based 5-element reference is
gone, with no backward compatibility: it never shipped in a release.
- On PHP 8.6, first-class callables declared in a constant expression of another
class (`#[When(Validators::check(...))]`) or over a global function
(`#[When(strlen(...))]`) get their declaring class from the engine and
serialize as a (site-based) declaration-site reference with no
`allow_named_closures` opt-in -- the same payload the extension produces on
8.5 through ReflectionAttribute provenance, and that the polyfill produces.

- On PHP 8.4+, `deepclone_from_array()` now creates object nodes whose
payload slots or replayed `__unserialize` state carry a named-closure or
const-expr-closure marker as
Expand Down
Loading