Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:113501 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 69682 invoked from network); 13 Mar 2021 16:58:13 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 13 Mar 2021 16:58:13 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4B6F51804B4 for ; Sat, 13 Mar 2021 08:51:16 -0800 (PST) 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_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-ot1-f52.google.com (mail-ot1-f52.google.com [209.85.210.52]) (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 ; Sat, 13 Mar 2021 08:51:16 -0800 (PST) Received: by mail-ot1-f52.google.com with SMTP id 75so5082464otn.4 for ; Sat, 13 Mar 2021 08:51:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=PLSDIZ6Thwbcexe3CSIIWs23mpIJ/3LjyluS88vAAbQ=; b=hiIX2xvF3frYcgskxaODyRPASmPeI4lrwpHjv1kPN0S8b9BI86QOwRFcUEBtb30J7m l4k/Y19FYTcXzeY5tNuIsNm6slXaU/aOe+jcFYLSqQjy3Hj9TwosRG2A57/IyV9tiIQ0 BWpbM6n/wg+QC9VVKFopMXS7qIjtaw0hGMnP09HTm08nJaJrY6AEUDYBR5RIYNFeURdV UWy9fdVRpqT9VrESfavtPuJh2U5H6i/SOyr+0ihQD+kCvvSwCDa4wFDJMIuIfkFJHQKC n5Ay3CIIWwsIcIZq5pXLLBF2VAoFz8O6+HqSUKimQozgFLzV3gj2ir61GdU5mTbbbewR uwdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=PLSDIZ6Thwbcexe3CSIIWs23mpIJ/3LjyluS88vAAbQ=; b=BH26G8LempNHaNGh7ByHbs5qgt39IqyFlgtNZjxjac1HKgEQxIePPQdHGAB+/z1TQa SjiyMflRIa+xUnomKKirVoyygkGkt4SC1d+jJvMFcwy7Ndni3KVtkUfmvz0pLdk+DMgq 4U/tLpccc8tfG5rRySupp82S2a+JybqGYON7L2UUh0cIwTYonWz1AUY8cM0pjkQ0lF7e a4On+XxoMwYLbq92oj+d5YvYlbStDlqdk57PNZ7k1X+FJAyRwvjD/i4GE32yFeyLEHzR EnZg8Xf3FWIWmY3/0C5o7lXcxAct53LDqnzlFuLPZbLwxJ/Ja8dHpIExeq1PmFJBdieq e1Yw== X-Gm-Message-State: AOAM532255xvgW+lo7nnPaLPvoLjB/BppEVWDWnCt9ulc7YQ8uyx+OMb 6QONaf6mf700bGC1Gce/jdjeFZgxwC3IXro/cTTGYDGBAdCrZQ== X-Google-Smtp-Source: ABdhPJwJqUBxbZr6J5AV97/9L8ryzW82VzwMZoWgFuHs28l6NCNOZc0wvVda+5Occp/dqgIe9ua4hnZwflRyMWOKCns= X-Received: by 2002:a9d:6a0a:: with SMTP id g10mr7737541otn.236.1615654275231; Sat, 13 Mar 2021 08:51:15 -0800 (PST) MIME-Version: 1.0 Date: Sat, 13 Mar 2021 16:51:04 +0000 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="00000000000027b23e05bd6dd312" Subject: Built-in decorator attribute? From: davidgebler@gmail.com (David Gebler) --00000000000027b23e05bd6dd312 Content-Type: text/plain; charset="UTF-8" With the introduction of attributes in PHP 8, this new behaviour is still quite sparsely documented. Some of the articles I've seen out there, though, liken PHP's attributes to similar constructs in other languages including decorators in Python. Attributes are not the same thing as (Python's concept of) decorators and they shouldn't be confused; a decorator is a function which wraps another function and is automatically called in place of the wrapped function. This isn't currently possible in PHP. Using frameworks like Symfony, we can start to build things like this: class UserProfileController { #[LoginRequired] public function editProfile(...) { } } but the logic of enforcing our "require the user to be logged in" decorator relies on the surrounding framework controlling the flow of execution, reading the attribute and deciding whether to call the decorated method editProfile() at all. What we *can't* do is something like this: class Foo { private function timer(callable $wrapped) { $start = microtime(true); $wrapped(); $end = microtime(true); $total = $end - $start; echo "Executed function in $total second(s)\n"; } #[timer] public function bar($a, $b) { ... } #[timer] public function baz($a, $b) { ... } } What I'm wondering is whether there's a desire / interest for a built-in attribute to provide this kind of behaviour modification. I'm thinking something like class Foo { private function timer(callable $wrapped) { ... } #[Decorator([self::class, 'timer'])] public function bar() { echo "Bar"; } } Where this would result in any call to $foo->bar() being equivalent to as if the above were defined as: class Foo { private function timer(callable $wrapped) { ... } public function __bar() { echo "Bar"; } public function bar() { return $this->timer([$this, '__bar']); } } I'm not saying I have the skills to implement this attribute (though I'd happily try), I'm not even in a position to propose a draft RFC at this stage, just throwing the idea out there to get a feel for what people think of the concept? Regards, Dave --00000000000027b23e05bd6dd312--