Bug #78455 [Com]: Access violation of private trait members

From: Date: Sun, 25 Aug 2019 00:46:36 +0000
Subject: Bug #78455 [Com]: Access violation of private trait members
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-222401@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78455&edit=1 ID: 78455 Comment by: developmenthero at gmail dot com Reported by: developmenthero at gmail dot com Summary: Access violation of private trait members Status: Not a bug Type: Bug Package: Scripting Engine problem Operating System: Windows 10 PHP Version: 7.3.8 Block user comment: N Private report: N New Comment: Thank you @requenix for bringing some light in the darkness. I guess i've been tricked a litte by the german tranlastion of the trait documentation wich only talks about "methods" whereas the english version speaks of "inherited members" and mentions an "insertion" of them. If this is defined behaviour, i guess it may worth to mention it in the documention and this ticket can be closed. Sorry for creating an useless Bugticket. ;-) Previous Comments: ------------------------------------------------------------------------ [2019-08-25 00:17:18] requinix@php.net Oh, just noticed it's __get in this new stuff, not __set. So correction: > var_dump($B->value); Would not be valid because B::$value is private so you cannot access it outside the class, but you have __get() so it will intercept the property access and return the string that it does. ------------------------------------------------------------------------ [2019-08-25 00:14:26] requinix@php.net > Shouldn't it be possible to access private fields of traits from a different scope than > the trait itself? First thing to understand is that the trait isn't some special form of class. Nor is it a set of rules like an interface. It's a bunch of things that PHP will copy and paste into whatever class wants to use it. No really. It's sometimes described as "language-assisted copy and paste" because that's an accurate description of how it works. A's "private $value = 1;" is copied and pasted into B, and B ends up with its very own "private $value = 1;" Same for getValue() and __set(). So > var_dump($B->getValue()); Valid. You're calling B::getValue() which tries to access B::$value which is perfectly fine. > var_dump($B->value); Not valid. B::$value is private so you cannot access it outside the class. ------------------------------------------------------------------------ [2019-08-25 00:03:15] developmenthero at gmail dot com Interestingly i just realized that __get won't be called from inside child-classes, since i upgraded from 7.2.4 to 7.3.7(now /.3.8). But clarify: Shouldn't it be possible to access private fields of traits from a different scope than the trait itself? Pardon me, i stripped down the snippet: <?php declare(strict_types=1); trait A { private $value = 1; public function getValue() { return $this->value; } public function __get($name) { return "hello world"; } } class B { use A; public function getValue() { return $this->value; } } $B = new B(); var_dump($B->getValue()); var_dump($B->value); ------------------------------------------------------------------------ [2019-08-24 23:20:25] requinix@php.net Thank you for this bug report. To properly diagnose the problem, we need a short but complete example script to be able to reproduce this bug ourselves. A proper reproducing script starts with <?php and ends with ?>, is max. 10-20 lines long and does not require any external resources such as databases, etc. If the script requires a database to demonstrate the issue, please make sure it creates all necessary tables, stored procedures etc. Please avoid embedding huge scripts into the report. > Prior to v7.3, "A::__set()" would be triggered here. Nope. https://3v4l.org/5XSGH ------------------------------------------------------------------------ [2019-08-24 23:17:14] developmenthero at gmail dot com Description: ------------ Private members of traits are (at least) since v7.3.7 accessible from within "using" classes now. Unfortunately this broke triggering __get() and __set() methods within traits. Test script: --------------- trait A { private $value = 1; public function getValue() { return $this->value; } public function __set($name, $val) { var_dump($name, $val); } } class B { use A; public function setValue($value) { // Prior to v7.3, "A::__set()" would be triggered here. $this->value = $value; } } $B = new B(); var_dump($B->getValue()); $B->setValue(12); var_dump($B->getValue()); ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=78455&edit=1

« previous php.bugs (#222401) next »