Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115810 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 75338 invoked from network); 25 Aug 2021 12:11:44 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 25 Aug 2021 12:11:44 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AEBF11804BE for ; Wed, 25 Aug 2021 05:45:54 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 25 Aug 2021 05:45:54 -0700 (PDT) Received: by mail-lj1-f172.google.com with SMTP id s3so43384703ljp.11 for ; Wed, 25 Aug 2021 05:45:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=3mNcmXCqQ4uaHuFRsQANXkgubGSxxi7q4/p8FyfWaVo=; b=b/0L4BnMV20eak74hhw6twRN61kqAfUN+YEAz+gLSvUOCiVqd7l1/TdtaCeZWw4RN+ oCmvOXcgf2mIb2aT4fRXYmoqniDBlMonPUE+DQUnSGS/hmsffJS9+esHDVNwXkl3vPF9 TVqPt1O63DRjXGo09oc91q42DqFh/wROOdIxVLs8OnKxnzKsINGZLg3yon4mf27NKi76 zILtHh41Ec3R/chyig8ppb5g+kLI3NVkmm0+ztCW/CFW41RZKiq/ZMsM+yUU41+eSAoG 5VVVd9q2wtKzFJqGQ8Jsu1NXuvf8KcCuWNMvdDp5/5+mkOeF5BSyc3PEmOuDZ8PfWk3N 4HHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=3mNcmXCqQ4uaHuFRsQANXkgubGSxxi7q4/p8FyfWaVo=; b=MRiz59jNjD4E/9P4AsPW91oaDir5IS9RPN4mcGvN/E65FmhdnKqusJTjyCs+duBFVx xWYha7c3gPn7KLIlsg4kELlVuPQii4R+xgt3ZNwdk+dyy6ERlnOt8RTGlmkjcPEIAThM G6tSTVgn7tUjxkVdY0kL6ZY76zk1ekXJmW64YS90KQEQYqYvI/StO4io7VVVY9X+84CA UOrlta4kKDRP3DsuQ7OwuCf38bQk9b+bGt1oRFCJ6bbUHecJd1SNiISF3MdEyZXNtqXz 9pjtQuTQ71SlK10msyvxKIvM3RehoLJ1GPwCIsoc2EMJn8PQut+c8nt04kzpsdJrkiJN vOCQ== X-Gm-Message-State: AOAM533vJvZX05oIjUfREKK7oHHd2lPspZhknpyUp7p/IRFph+XYMP/g HRS0XwhnpdPY4sUuC2wdOIuBC1H3gGghwyBkFqY= X-Google-Smtp-Source: ABdhPJx7KEYkDj6u6fDgRDUfLe5AtwC0tY+qinEEwpFMxm+RnzmOYCFI/g3L8bn0yy0MvapsetohwqxwWMFVQkiXjZc= X-Received: by 2002:a2e:9304:: with SMTP id e4mr36112661ljh.244.1629895551681; Wed, 25 Aug 2021 05:45:51 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 25 Aug 2021 14:45:35 +0200 Message-ID: To: Rowan Tommins Cc: PHP internals Content-Type: multipart/alternative; boundary="00000000000061099805ca61a153" Subject: Re: [PHP-DEV] [RFC] Deprecate dynamic properties From: nikita.ppv@gmail.com (Nikita Popov) --00000000000061099805ca61a153 Content-Type: text/plain; charset="UTF-8" On Wed, Aug 25, 2021 at 12:45 PM Rowan Tommins wrote: > On 25/08/2021 11:02, Nikita Popov wrote: > > I'd like to propose the deprecation of "dynamic properties", that is > > properties that have not been declared in the class (stdClass and > > __get/__set excluded, of course): > > > > https://wiki.php.net/rfc/deprecate_dynamic_properties > > > This is a bold move, and in principle seems sensible, although I'm > slightly scared how many places will need fixing in legacy code bases. > > I have a couple of concerns with using stdClass as the opt-in mechanism: > > * The name of that class already leads to a lot of confusion about its > purpose - it's not actually "standard" in any way, and new users seeing > it as a base class are even more likely to mistake it as some kind of > "universal ancestor". Would it be feasible to introduce an alias like > "DynamicObject" which more clearly defines its role? > > * Adding a parent to an existing class isn't always possible, if it > already inherits from something else. Perhaps the behaviour could also > be available as a trait, which defined stub __get and __set methods, > allowing for the replacement of the internal implementation as you've > described? > So, a few thoughts: First of all, I should say that "extends stdClass" is not so much an explicit escape hatch I built into this, it's more something that arises naturally: We obviously need to keep support for dynamic properties on stdClass, and if we do so, I would expect that to apply to subclasses as well. As such, I believe that the "extends stdClass" escape hatch is something that's going to work anyway -- the only question would be whether we want to provide additional opt-ins in the form of interfaces/traits/attributes/etc. Second, I consider "extends stdClass" to be something of a last-ditch option. If you encounter a dynamic property deprecation warning, you should generally resolve it in some other way, and only fall back to "extends stdClass" as the final option. All that said, yes, we could add a trait. It would basically be ArrayLikeObject from the RFC with "class" replaced by "trait". However, I'm not sure this is really worthwhile. The nice thing about extending stdClass is that it a) gives you much more efficient property access than __get/__set and b) matches current behavior. Implementing such a trait, even if bundled, doesn't really give you any advantages over implemening __get/__set yourself. It would not make use of an optimized implementation (or at least, the implementation would still be calling real __get/__set methods) and the behavior would be limited to what the trait provides. A custom implementation is not significantly harder (the minimal implementation is five lines of code) but gives you more control, e.g. you might want just the minimal implementation, or you might want to also support Traversable, have a custom __debugInfo(), etc. My preliminary position would be that if a) you can't avoid dynamic properties in any other way and b) you can't extend stdClass either, then you should go with c) implementing __get/__set yourself, as appropriate for the given use-case. Regards, Nikita --00000000000061099805ca61a153--