Re: [PHP-DEV] Re: [RFC] Deprecate dynamic properties

This is only part of a thread. view whole thread
  116268
October 13, 2021 08:19 rowan.collins@gmail.com (Rowan Tommins)
On 13/10/2021 02:43, Tim Starling wrote:
> I think it would still be the biggest compatibility break since PHP > 4->5.
I think this is a rather large exaggeration. It's certainly a use case we need to consider, but it's not on the scale of call-time pass-by-reference, or removing the mysql extension, or a dozen other changes that have happened over the years.
> As the RFC notes, you could migrate to WeakMap, but it will be very > difficult to write code that works on both 7.x and 8.2, since both > attributes and WeakMap were only introduced in 8.0.
Firstly, writing code that works on both 7.x and 8.2 will be easy: ignore the deprecation notices. As discussed elsewhere, treating a deprecation as a breaking change makes a nonsense of deprecating anything. Secondly, I would be surprised if libraries using this trick don't already have helper functions for doing it, in which case changing those to use WeakMap and falling back to the dynamic property implementation on old versions is easy. Maybe I'm missing some difficulty here? if ( class_exists('\\WeakMap') ) {     class Attacher {         private static $map;         public static function setAttachment(object $object, string $name, $value): void         {             self::$map ??= new WeakMap;             $attachments = self::$map[$object] ?? [];             $attachments[$name] = $value;             self::$map[$object] = $attachments;         }         public static function getAttachment(object $object, string $name)         {             self::$map ??= new WeakMap;             return self::$map[$object][$name] ?? null;         }     } } else {     class Attacher {         public static function setAttachment(object $object, string $name, $value): void         {             $attachments = $object->__attached_values__ ?? [];             $attachments[$name] = $value;             $object->__attached_values__ = $attachments;         }         public static function getAttachment(object $object, string $name)         {             return $object->__attached_values__[$name] ?? null;         }     } } $foo = new Foo; Attacher::setAttachment($foo, 'hello', 'world'); echo Attacher::getAttachment($foo, 'hello'), "\n";
> I would support an opt-in mechanism, although I think 8.2 is too soon > for all core classes to opt in to it. We already have classes that > throw an exception in __set(), so it would be nice to have some > syntactic sugar for that.
I proposed "locked classes" a while ago, but consensus was that this was the wrong way around. One suggestion that did come up there was a block-scopable declare which would allow manipulating dynamic properties, even without the target class's co-operation. However, I think WeakMap (with a helper and a fallback like above) is probably a superior solution for that, because adding properties outside the class always carries risk of name collision, interaction with __get, etc Regards, -- Rowan Tommins [IMSoP]
  116269
October 13, 2021 09:17 guilliam.xavier@gmail.com (Guilliam Xavier)
Off-topic:

if ( class_exists('\\WeakMap') ) {
>
People should stop using a leading slash in FQCN *strings*. \Foo::class is "Foo", not "\Foo". It might work generally but that's asking for problems (e.g. for autoloaders). (Sorry.)
  116270
October 13, 2021 09:21 guilliam.xavier@gmail.com (Guilliam Xavier)
On Wed, Oct 13, 2021 at 11:17 AM Guilliam Xavier xavier@gmail.com>
wrote:

> Off-topic: > > if ( class_exists('\\WeakMap') ) { >> > > People should stop using a leading slash in FQCN *strings*. \Foo::class > is "Foo", not "\Foo". It might work generally but that's asking for > problems (e.g. for autoloaders). > > (Sorry.) >
And of course I mistyped "leading backslash"... Also externals.io seems to strip them, so: \\Foo::class is "Foo", not "\\Foo".
  116271
October 13, 2021 09:52 pierre-php@processus.org (Pierre)
Le 13/10/2021 à 11:17, Guilliam Xavier a écrit :
> Off-topic: > > if ( class_exists('\\WeakMap') ) { > People should stop using a leading slash in FQCN *strings*. \Foo::class is > "Foo", not "\Foo". It might work generally but that's asking for problems > (e.g. for autoloaders). > > (Sorry.) > And why not ? using the FQDN is 100% valid, autoloaders should take care
of this, not the end user. For what it worth, I'm using both, depending upon context, both can make sense. Regards, -- Pierre
  116272
October 13, 2021 12:42 rowan.collins@gmail.com (Rowan Tommins)
On 13/10/2021 10:17, Guilliam Xavier wrote:
> Off-topic: > > if ( class_exists('\\WeakMap') ) { > > > People should stop using a leading slash in FQCN *strings*.  > \Foo::class is "Foo", not "\Foo".  It might work generally but that's > asking for problems (e.g. for autoloaders). > > (Sorry.)
Hah, good point. I should probably just have just used ::class anyway (in which case the leading backslash is the quickest way of the sample code being pasteable into some other file): if ( class_exists(\WeakMap::class) ) { There's probably a bunch of other style no-noes in that example, but I did at least test it worked. :) Regards, -- Rowan Tommins [IMSoP]
  116273
October 13, 2021 13:18 pierre-php@processus.org (Pierre)
Le 13/10/2021 à 14:42, Rowan Tommins a écrit :
> On 13/10/2021 10:17, Guilliam Xavier wrote: >> Off-topic: >> >>     if ( class_exists('\\WeakMap') ) { >> >> >> People should stop using a leading slash in FQCN *strings*. >> \Foo::class is "Foo", not "\Foo".  It might work generally but that's >> asking for problems (e.g. for autoloaders). >> >> (Sorry.) > > > Hah, good point. I should probably just have just used ::class anyway > (in which case the leading backslash is the quickest way of the sample > code being pasteable into some other file): > > if ( class_exists(\WeakMap::class) ) { > > There's probably a bunch of other style no-noes in that example, but I > did at least test it worked. :) > > > Regards, > I am surprised that:
if ( class_exists(\WeakMap::class) ) { Actually works when the class does not exist. It's not really surprising, I mean the FQDN::class in the end only resolve to a simple string no matter that the class exists or not, but, I'm being the devil's advocate here, there are use case were you would want the engine to crash when you explicitly reference/use a non existing class, even when it's only its name. I'm sorry this is off-topic. -- Pierre