Skip to content

Add property_is_initialized - #41

Merged
veewee merged 3 commits into
mainfrom
feature/property-is-initialized
Oct 16, 2026
Merged

veewee merged 3 commits into
mainfrom
feature/property-is-initialized

Conversation

@veewee

@veewee veewee commented Oct 15, 2026

Copy link
Copy Markdown
Owner

php-soap/encoding wants to stop writing xsi:nil for optional elements whose property was never set (php-soap/encoding#71). After optional_property() reads null, the encoder has to tell a property that holds null apart from one that is missing or uninitialised. The answer follows the same PHP lookup rules the lens already handles, so I put it here instead of in the encoder.

Reflect\property_is_initialized(object $object, string $name): bool resolves the property in the same order as optional_property(): the class itself, then a dynamic property, then private properties on parent classes. It keeps no cache, returns no ReflectionProperty and never calls __get. When PHP throws while checking, for example in a lazy object whose initializer fails, it reports the property as present, so a caller keeps writing the value it read.

I gave the function its own body instead of pulling a shared resolver out of optional_property(), so the lens read path stays as it is. A parity test runs both over the same fixtures to catch drift.

On PHP 8.4, ReflectionProperty::isInitialized() initialises a lazy ghost or proxy, so calling this on a lazy object that nobody touched yet has that side effect.

Cost per call next to optional_property() (ns, PHP 8.4, xdebug off, median of 3 phpbench rounds):

case optional_property property_is_initialized
typed, initialised 160 117
typed, uninitialised 165 115
stdClass, present 94 71
stdClass, missing 100 82
private property on a parent 200 154

Tells an absent or uninitialised property apart from one that holds null, resolving the property in the same order as optional_property. A parity test keeps both in line.
veewee added a commit to veewee/encoding that referenced this pull request Oct 16, 2026
veewee/reflecta#41 adds Reflect\property_is_initialized(). Until 1.2.0 is tagged the branch comes in through a VCS repository aliased as 1.2.0. This commit gets replaced by a ^1.2 constraint after the release, so the branch cannot be merged before that.
@veewee
veewee merged commit ff09781 into main Oct 16, 2026
13 checks passed
@veewee
veewee deleted the feature/property-is-initialized branch October 16, 2026 07:16
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