|
A materialized value used to cross as a constructor call: the class name,
the arguments, and any post-construction setter. Describing a real
instance that way needed a ReflectionProperty read for every field the
class exposes no getter for, and state no constructor takes (an unset
pretty string, a Link built without a pretty constraint) had no faithful
call to describe it at all.
The value now crosses as the object record serialize() writes for it,
which unserialize() revives without running a constructor, so both sides
transfer the state itself instead of a recipe for rebuilding it. The PHP
half keeps only the class list (also the allowed_classes list of every
frame payload) and the UTC rebasing of dates; describe(), build() and the
reflection are gone.
The wire codec gains O: records (PluginValue::PhpObject) and r: back
references, whose resolution reproduces PHP's numbering of every value in
a payload; a cyclic object graph and a PHP reference (R:) are rejected.
Two behaviours change with it: a date crosses carrying timezone_type 3
"UTC" rather than a +00:00 offset, which is what ArrayLoader builds a
release date as, and a Link subclass crosses as a P-table entity instead
of being silently downgraded to a plain Link.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|