On Mon, Mar 11, 2019 at 1:14 PM Rowan Collins <rowan.coll...@gmail.com>
wrote:

> Hi Nikita,
>
> On Mon, 11 Mar 2019 at 11:27, Nikita Popov <nikita....@gmail.com> wrote:
>
> > The solution I would prefer is the ability to declare that within a
> > project, all interactions with objects (whether they are my own or come
> > from 3rd parties) should disallow the creation of dynamic properties.
> This
> > differs from your proposal in two important points:
> >  1. You cannot create dynamic properties on objects even if they come
> from
> > 3rd-party code you do not control.
> >  2. 3rd-party code may interact with your objects (and it's own) however
> > it likes. It is not affected by the disabling of dynamic properties in
> your
> > project code.
> >
>
>
> That's an interesting approach. I think it's conceptually a lot more
> complicated (and probably more complicated to implement, too) - the same
> object would behave in different ways in different contexts. There are also
> edge cases to define which the current proposal doesn't need to worry
> about, like stdClass, and objects which were created in one scope and
> manipulated in another:
>
> declare(strict_properties=0) {
>     class Foo {}
>     $foo = new Foo;
>     $foo->bar = 42;
> }
> declare(strict_properties=1) {
>     echo $foo; # Is $bar now 'defined', or do we only count the properties
> in the original class definition?
> }
>

I'd expect it to be defined, especially as it allows interoperating with
libraries that are missing property declarations and set dynamic properties
(intentionally).

More importantly, you would have to check that third-party code was
> declaring the properties you needed before enabling it. For instance, a
> library might document that you should set `$handler->debug = true`, read
> that property internally, but never declare it; you'd then have to patch
> the library before you could run in strict_properties mode.
>
> It feels like at that point, we might as well just deprecate dynamic
> properties altogether - which I'm beginning to think is the best approach.
>
> To put it explicitly, what are the use cases where you'd turn such a flag
> off?
>

You'd turn it off in the case you mentioned: A 3rd-party library that
relies on dynamic properties. The idea is that you disable dynamic
properties globally for your own code, but can opt back in for cases where
they are necessary for some reason (most likely interoperability, but
possibly also code doing weird Marco things).

This allows you to single out some piece of code as "here be dragons",
rather than keeping dragons as the default state :)

Removing the ability to use dynamic properties (even excluding stdClass) is
probably not feasible on a short timetime. However, I think that having a
directory-scoped declare would also be useful for that, because it allows a
more gradual migration. You can start with having strict_properties default
to false and have interested parties opt-in. Then you can flip the default
to true, while still giving people who rely heavily on it the ability to
opt-out. Removal would be the final stage where the ability to opt-out goes
away.

Regarding optimizations that your RFC allows: In theory we could drop the
properties_table member (8 bytes) for objects of locked classes. In
practice this is probably not beneficial as access to the embedded property
table would no longer be at a fixed offset.

Nikita

> 1. The BC break section is not terribly clear due to the use of
> > "semi-reserved". I initially assumed that this was a contextual keyword
> > (i.e. only has special meaning immediately before "class") but apparently
> > this is a normal reserved keyword in the implementation (i.e. no classes,
> > functions, namespaces etc named "locked").
> >
>
>
> Oops, I'll hold my hands up to not actually testing that. I think I took
> that wording from a comment in the parser, but probably didn't read it
> properly.
>
>
>
> 2. It is possible to break a reference by reassigning it to another
> > reference, like so:
> >
> >     $null = null;
> >     $this->prop =& $null;
> >     unset($null);
> >
> > This is not quite as good as unsetting because it leaves behind an rc=1
> > reference, but that would be the way to remove a reference without
> unset().
> >
>
>
> Huh, cunning. :)
>
> Regards,
> --
> Rowan Collins
> [IMSoP]
>

Reply via email to