Bug #72174 [Opn]: ReflectionProperty#getValue() causes __isset call
| From: | nikic@php.net | Date: | Sat, 07 May 2016 18:59:56 +0000 |
| Subject: | Bug #72174 [Opn]: ReflectionProperty#getValue() causes __isset call | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-200942@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72174&edit=1
ID: 72174
Updated by: nikic@php.net
Reported by: ocramius at gmail dot com
Summary: ReflectionProperty#getValue() causes __isset call
Status: Open
Type: Bug
Package: Reflection related
PHP Version: 7.0.6
Block user comment: N
Private report: N
New Comment:
To summarize OTR discussion:
The issue is that ReflectionProperty::getValue() currently performs a "silenced read",
which is roughly equivalent to doing isset($obj->prop) ? $obj->prop : NULL. Prior to PHP 7.0.6
the isset($obj->prop) part did not result in a call to __isset() due to a bug in the magic method
implementation.
However, it can be be argued that ReflectionProperty::getValue() should not be performing a silenced
read in the first place. It should simply return the value of $obj->prop. If we make this change
then the behavior described in the bug report will go back to what it was. On the other hand, this
means that using ReflectionProperty::getValue() to read an undefined property will throw an
undefined property notice (currently suppressed: https://3v4l.org/vdOjh).
The current plan is to change ReflectionProperty::getValue() to perform the read without silencing.
Previous Comments:
------------------------------------------------------------------------
[2016-05-07 18:48:57] ocramius at gmail dot com
Bug seems to really only affect reflection access: https://3v4l.org/GY4NC
------------------------------------------------------------------------
[2016-05-07 18:27:36] ocramius at gmail dot com
Note: bug was discovered in builds of ProxyManager at https://travis-ci.org/Ocramius/ProxyManager/jobs/128480921#L384
------------------------------------------------------------------------
[2016-05-07 18:25:19] ocramius at gmail dot com
See https://3v4l.org/9BipO
------------------------------------------------------------------------
[2016-05-07 18:24:13] ocramius at gmail dot com
Description:
------------
When using
ReflectionProperty#getValue($object) on a $object with an
unset() property and defined __isset and __get methods, the
__get method is called, while it should only use __get.
Note that this is a bug that affects only PHP 7.0.6, and isn't part of 7.0.5.
Test script:
---------------
<?php
class Foo
{
private $bar;
public function __construct()
{
unset($this->bar);
}
public function __isset($name)
{
var_dump(__METHOD__);
return true;
}
public function __get($name)
{
var_dump(__METHOD__);
return $name;
}
}
$instance = new Foo();
$reflectionBar = (new ReflectionProperty(Foo::class, 'bar'));
$reflectionBar->setAccessible(true);
$closureBar = (function (Foo $instance) {
return $instance->bar;
})->bindTo(null, Foo::class);
var_dump($reflectionBar->getValue($instance));
var_dump($closureBar($instance));
Expected result:
----------------
string(10) "Foo::__get"
string(3) "bar"
string(10) "Foo::__get"
string(3) "bar"
Actual result:
--------------
string(12) "Foo::__isset"
string(10) "Foo::__get"
string(3) "bar"
string(10) "Foo::__get"
string(3) "bar"
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=72174&edit=1