|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78921 When Reflection triggers class load, property visibility is incorrect
Submitted: 2019-12-07 06:57 UTC Modified: 2019-12-13 15:30 UTC
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: theilig at box dot com Assigned:
Status: Closed Package: Reflection related
PHP Version: 7.3.12 OS: centos7 OSX 18.7.0
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: theilig at box dot com
New email:
PHP Version: OS:


 [2019-12-07 06:57 UTC] theilig at box dot com
If a class tries to use reflection to read a property of a second class, and that second class has a property or a const that is initialized by a const reference to a third class, The scope for visibility of properties is incorrect, The third class will not be able to access it's own private static properties, but instead will have access to private static properties of a different class!  See the example code for more info.

OtherClass::$test isn't as private as it thinks!

Fatal error: Uncaught Error: Cannot access private property PrivateStatic::$privateStaticVarArray in /Users/theilig/code/PhpBug/PrivateStatic.php on line 9

Error: Cannot access private property PrivateStatic::$privateStaticVarArray in /Users/theilig/code/PhpBug/PrivateStatic.php on line 9

Call Stack:
    0.0004     395896   1. {main}() /Users/theilig/code/PhpBug/ThirdClass.php:0
    0.0010     398848   2. ReflectionProperty->getValue() /Users/theilig/code/PhpBug/ThirdClass.php:9
    0.0010     398968   3. spl_autoload_call() /Users/theilig/code/PhpBug/ThirdClass.php:9
    0.0010     399008   4. {closure:/Users/theilig/code/PhpBug/ThirdClass.php:2-4}() /Users/theilig/code/PhpBug/ThirdClass.php:9
    0.0011     402480   5. include('/Users/theilig/code/PhpBug/PrivateStatic.php') /Users/theilig/code/PhpBug/ThirdClass.php:3
    0.0011     402480   6. PrivateStatic::init() /Users/theilig/code/PhpBug/PrivateStatic.php:12

You can see from the stack that the current function is PrivateStatic::init() which should be able to access private static variables in the PrivateStatic class, but instead was able to read OtherClass::$test which is private.

The code works correctly if either 
1) The third class (PrivateStatic in the example) is forcefully loaded before the reflection call "class_exists('PrivateStatic');


2) The field in the second class is public, and is referenced directly rather than via Reflection.

What I've seen via xdebug is that in php 7.1.29 
$reflectionClass = new ReflectionClass('OtherClass');
will trigger the loading of PrivateStatic (and everything works correctly)

However in php 7.3.12 
$reflectionClass = new ReflectionClass('OtherClass');
will only load OtherClass, and PrivateStatic isn't loaded until
$value = $reflectionProperty->getValue();

When the getValue call triggers the loading of PrivateStatic (and the running of the top level call to PrivateStatic::init() ) then it appears to be picking up the scope of OtherClass  

Test script:

% php ThirdClass.php

Expected result:
Expected result is:

PHP Fatal error:  Uncaught Error: Cannot access private property OtherClass::$test in /Users/theilig/code/PhpBug/PrivateStatic.php:9

Actual result:
OtherClass::$testisn't as private as it thinks!
PHP Fatal error:  Uncaught Error: Cannot access private property PrivateStatic::$privateStaticVarArray in /Users/theilig/code/PhpBug/PrivateStatic.php:10


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-12-07 09:28 UTC]
-Status: Open +Status: Verified
 [2019-12-07 09:28 UTC]
Introduced with commit db7ead0[1].  Inserting a var_dump($self)
in PrivateStatic::init() prints NULL.

[1] <;a=commit;h=db7ead0768076da486a9c98264061113233deb7f>
 [2019-12-13 15:30 UTC]
Single file:

spl_autoload_register(function($className) {
    if ($className == 'PrivateStatic') {
        class PrivateStatic
            const SOME_CONST = 13;
            private static $privateStaticVarArray = ['a', 'b', 'c'];
            private static $otherStatic;
            public static function init()
                self::$otherStatic = self::$privateStaticVarArray;
class OtherClass
    const MY_CONST = PrivateStatic::SOME_CONST;
    public static $prop = 'my property';
$reflectionClass = new ReflectionClass('OtherClass');
$reflectionProperty = $reflectionClass->getProperty('prop');
$value = $reflectionProperty->getValue();
//$value = OtherClass::$prop;
echo "Value is $value\n";
 [2019-12-13 15:39 UTC]
Automatic comment on behalf of
Log: Fixed bug #78921
 [2019-12-13 15:39 UTC]
-Status: Verified +Status: Closed
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Jul 18 21:01:27 2024 UTC