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 >> >