On Wed, Feb 6, 2019 at 1:38 PM Benjamin Morel <benjamin.mo...@gmail.com>
wrote:

> Hi Nikita,
>
> While playing with typed properties, something that annoys me a lot, in
> the context of a data mapper, is not to be able to use isset() to check
> whether an object's property is initialized. The issue was already there
> with properties that have been explicitly unset(), but will be
> exacerbated by typed properties, which will be unset *by default*.
>
> Sure, we have ReflectionProperty::isInitialized(), but reflection is slow
> compared to direct property access, when reading a lot of objects.
>
> For example, check these 3 ways of reading initialized public/protected
> object properties by name, along with their timings for 100,000 iterations
> (benchmark here
> <https://gist.github.com/BenMorel/9a920538862e4df0d7041f8812f069e5#file-reflection-vs-array-cast-benchmark-php>
> ):
>
> Using reflection: (890 ms, down to 384 ms using pre-instantiated
> ReflectionProperty objects)
>
>     $r = new \ReflectionClass($class);
>>     foreach ($props as $prop) {
>>         $p = $r->getProperty($prop);
>>         $p->setAccessible(true);
>>         if ($p->isInitialized($object)) {
>>             $values[$p->getName()] = $p->getValue($object);
>>         }
>>     }
>
>
> Using array cast: (193 ms)
>
>     foreach ((array) $object as $key => $value) {
>>         // Remove the "\0*\0" in front of protected properties
>>         $pos = strrpos($key, "\0");
>>         if ($pos !== false) {
>>             $key = substr($key, $pos + 1);
>>         }
>>         $values[$key] = $value;
>>     }
>
>
> Using a bound closure and isset(): (145 ms)
>
>
>>     (function() use ($props, & $values) {
>>         foreach ($props as $prop) {
>>             if (isset($this->{$prop})) { // skips NULL values as well :-(
>>                 $values[$prop] = $this->{$prop};
>>             }
>>         }
>>     })->bindTo($object, $object)();
>
>
> Unfortunately, while the last approach is the fastest, and IMO the
> cleanest one, it is currently unusable because there is no way to
> differentiate between an uninitialized property and a NULL property.
>
> Would it be possible to introduce another isset() operator, that would
> return true for NULL values?
> Note that this would also be useful when checking if an array key exists,
> instead of having to switch from isset() to array_key_exists() when the
> array may contain NULL values.
>

It's possible and someone even worked on an implementation at some point (
https://github.com/php/php-src/pull/1530), but I don't believe this ever
proceeded to the RFC stage. (I'm rather doubtful about introducing
something like this, due to the quite significant increase in conceptual
language complexity for little benefit. I definitely have no plans to
pursue such a feature myself.)

Nikita


> On Fri, 11 Jan 2019 at 17:38, Nikita Popov <nikita....@gmail.com> wrote:
>
>> On Mon, Oct 22, 2018 at 1:58 PM Sebastian Bergmann <sebast...@php.net>
>> wrote:
>>
>> > Am 26.09.2018 um 15:46 schrieb Nikita Popov:
>> > > I'm pleased to announce that the typed properties RFC has been
>> accepted
>> > > with 70 votes in favor and one vote against. We will work to finalize
>> and
>> > > merge the implementation in the next few days.
>> >
>> > Any update on when this will be merged? Thanks!
>> >
>>
>> Sorry for the long delay here. I've spent the last week fixing the
>> remaining issues and cleaning up the patch, and...
>>
>> ...Typed properties are now merged into master! [1]
>>
>> It would be great if people could start experimenting with typed
>> properties
>> (e.g. by migrating over existing @var annotations and seeing what
>> happens).
>> The earlier we find issues in the implementation or semantics, the better.
>>
>> Thanks to everyone who worked on this RFC and participated in discussions.
>> Special thanks to Bob Weinand who did most of the initial implementation
>> work on this RFC.
>>
>> Regards,
>> Nikita
>>
>> [1]:
>>
>> https://github.com/php/php-src/commit/e219ec144ef6682b71e135fd18654ee1bb4676b4
>>
>

Reply via email to