Req #67830 [Nab]: PropertyReflection->setAccessible(false) not affecting public properties

From: Date: Thu, 14 Aug 2014 08:17:11 +0000
Subject: Req #67830 [Nab]: PropertyReflection->setAccessible(false) not affecting public properties
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-187117@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=67830&edit=1 ID: 67830 User updated by: leuffen at continue dot de Reported by: leuffen at continue dot de Summary: PropertyReflection->setAccessible(false) not affecting public properties Status: Not a bug Type: Feature/Change Request Package: Reflection related Operating System: Linux PHP Version: 5.5.15 Block user comment: N Private report: N New Comment: I don't see why this should be a bad thing to do. (Maybe defining properties in DocBlock @property is a much better way than unsetting them. But that's not the point) The point is that although if we would, we have to store the actual data in an data-structure that differs from the IDEs point of view. So debugging etc. is much more complicated than it could be. --testscript- /** * Class Entity * * @property string $name */ class Entity { public function __construct() { } public function __set($name, $val) { echo "setting $name "; $this->$name = $val; $ref = new ReflectionObject($this); $ref->getProperty($name)->setAccessible(FALSE); } public function __get($name) { echo "getting $name"; } } $entity = new Entity(); $entity->name = "value"; echo $entity->name; --/testscript- Above example will call __get() once - and afterwards access the property direcly. If you have an better approach - please write me. Previous Comments: ------------------------------------------------------------------------ [2014-08-14 05:13:19] levim@php.net As specified in the comments, this is not a bug. ------------------------------------------------------------------------ [2014-08-14 04:42:18] datibbaw@php.net First of all, that's a horrendous way of doing things. You can accomplish this quite easily by using the @property DocBlock: /** * Class Entity * * @property string $name */ That said, ReflectionProperty::setAccessible(bool) only affects calls to ReflectionProperty::get/setValue(), it doesn't actually change anything in the target object. ------------------------------------------------------------------------ [2014-08-14 04:21:58] levim@php.net After looking into it more, this doesn't seem to be a bug. Only the property in the reflection object becomes accessible; it doesn't modify the $this instance. Can someone more knowledgeable in reflection review this? ------------------------------------------------------------------------ [2014-08-14 04:17:26] levim@php.net As a general PHP user I am shocked that you use it like this. Clearly abuse in my opinion. From a dev perspective, it probably should be supported if we claim it is supported in documentation. If not, it's just a bad API and we should change the API. ------------------------------------------------------------------------ [2014-08-12 14:33:38] leuffen at continue dot de Description: ------------ At present ReflectionProperty::setAccessible() works only one-way: Changing unaccessible Properties to accessible. setAccessible(false) will have no affect. This is complicated for frameworks using __get() and __set(): Our frameworks use the magic __get() and __set() methods to validate data or to load Entities from Database. To take advantage from common IDE's code-completion we declare these properties public and unset them whithin the constructor (and store the actual data whithin a private or protected property). It would be a great advantage for working with these Objects if we could use the ReflectionProperty::setAccessible() Method to change property visibility to private and enforce use of __get() and __set() methods. Test script: --------------- class Entity { public $name = "direct access"; public function __construct() { $ref = new ReflectionObject($this); foreach ($ref->getProperties() as $prop) { $prop->setAccessible(FALSE); } } public function __get($name) { return "access over __get()"; } } $o = new Entity(); echo $o->name; Expected result: ---------------- "access over __get()" Actual result: -------------- "direct access" ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=67830&edit=1

« previous php.bugs (#187117) next »