Bug #72177 [Asn]: Scope issue in __destruct after ReflectionProperty::setValue()

From: Date: Thu, 12 May 2016 21:23:58 +0000
Subject: Bug #72177 [Asn]: Scope issue in __destruct after ReflectionProperty::setValue()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201049@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72177&edit=1

 ID:                 72177
 Updated by:         nikic@php.net
 Reported by:        lbarnaud@php.net
 Summary:            Scope issue in __destruct after
                     ReflectionProperty::setValue()
 Status:             Assigned
 Type:               Bug
 Package:            Reflection related
 PHP Version:        7.0Git-2016-05-09 (Git)
 Assigned To:        dmitry
 Block user comment: N
 Private report:     N

 New Comment:

Note that this affects not only __destruct(), but also __get() and other magic. E.g. the call https://github.com/Ocramius/ProxyManager/blob/6e15877fc03cc211ce798d497a21208a44f7b726/tests/ProxyManagerTest/Functional/LazyLoadingGhostFunctionalTest.php#L403
results in an access level error in https://gist.github.com/Ocramius/e4f481dd1d4f93adffb0646a780d1217#file-foo5731cbdb7cfb2968834795-php-L125.


Previous Comments:
------------------------------------------------------------------------
[2016-05-12 15:48:59] nikic@php.net

Fallout from the EG(scope) removal. Now EG(fake_scope) will continue shadowing the scope, even
though we might reenter a differently scoped method.

This looks a bit tricky... maybe we should just avoid the fake scoping altogether and add an extra
scope argument to the property handlers?

------------------------------------------------------------------------
[2016-05-09 13:28:50] lbarnaud@php.net

Description:
------------
When __destruct() is called, following a ReflectionProperty::setValue() call, scopes seem to be
wrong.

In the following reproducing script, the method Child::__destruct() fails to set
$this->bar to null, with the error Cannot access protected property
Child::$bar.

I can reproduce this in git master, but not in any version from 3v4l.org.

Test script:
---------------
<?php

class Child
{
    protected $bar;

    public function __destruct()
    {
        $this->bar = null;
    }
}

class Parnt
{
    protected $child;

    public function doSomething()
    {
        $this->child = new Child();

        $prop = new \ReflectionProperty($this, 'child');
        $prop->setAccessible(true);
        $prop->setValue($this, null);
    }
}

$p = new Parnt();
$p->doSomething();

echo "OK\n";

Expected result:
----------------
OK

Actual result:
--------------
Fatal error: Uncaught Error: Cannot access protected property Child::$bar in /tmp/x.php:9
Stack trace:
#0 [internal function]: Child->__destruct()
#1 /tmp/x.php(23): ReflectionProperty->setValue(Object(Parnt), NULL)
#2 /tmp/x.php(28): Parnt->doSomething()
#3 {main}
  thrown in /tmp/x.php on line 9


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=72177&edit=1


Thread (5 messages)

« previous php.bugs (#201049) next »