开发者

Failed to get dynamic instance variables via PHP's reflection

开发者 https://www.devze.com 2023-02-08 16:45 出处:网络
I failed to get dynamic instance variables via PHP\'s reflection Sample code: <?php class Foo { public function bar()

I failed to get dynamic instance variables via PHP's reflection

Sample code:

<?php

class Foo
{
    public function bar()
    {         
        $reflect = new Reflect开发者_如何学JAVAionClass($this);
        $props   = $reflect->getProperties();
        var_export($props);
        die;
    }
}

$foo = new Foo();
$foo->a = "a";
$foo->b = "b";

$foo->bar(); // Failed to print out variable a and b

Any idea?


ReflectionClass::getProperties() gets only properties explicitly defined by a class. To reflect all properties you set on an object, use ReflectionObject which inherits from ReflectionClass and works on runtime instances:

$reflect = new ReflectionObject($this);

Or as Tim Cooper says, forget reflection and just use get_object_vars() instead.


You cannot use ReflectionClass in this situation. Replace your $props variable with the following to make it work:

$props = get_object_vars($this);

If there is no other method you need to call from ReflectionObject (see BoltClock's answer), then this is the simplest solution.


class Foo { }
$foo = new Foo();
$foo->a = "a";
$foo->b = "b";
echo Reflection::export(new ReflectionObject($foo));

// Object of class [ <user> class Foo ] {
//   @@ /var/www/files/r.php 2-2
//   - Constants [0] {
//   }
//   - Static properties [0] {
//   }
//   - Static methods [0] {
//   }
//   - Properties [0] {
//   }
//   - Dynamic properties [2] {
//     Property [ <dynamic> public $a ]
//     Property [ <dynamic> public $b ]
//   }
//   - Methods [0] {
//   }
// }


A detailed explanation on both answeres above

Given the instance of an anonymous class

$object             = new class()
{
    private $fooPrivate = 'barPrivate';

    public $fooPublic = 'barPublic';

    public static $fooStaticPublic = 'barStaticPublic';

    public function getProperties(): array
    {
        return get_object_vars( $this );
    }
};

$object->fooDynamic = 'barDynamic';

Getting the properties by reflection

with ReflectionClass

/** lists: `fooPrivate`, `fooPublic`, `fooStaticPublic` */
var_export(
    ( new ReflectionClass( $object ) )
        ->getProperties()
);

/** lists: `fooPublic`, `fooStaticPublic` */
var_export(
    ( new ReflectionClass( $object ) )
        ->getProperties( ReflectionProperty::IS_PUBLIC )
);

with ReflectionObject

/** lists: `fooPrivate`, `fooPublic`, `fooStaticPublic`, `fooDynamic` */
var_export(
    ( new ReflectionObject( $object ) )
        ->getProperties()
);

/** lists: `fooPublic`, `fooStaticPublic`, `fooDynamic` */
var_export(
    ( new ReflectionObject( $object ) )
        ->getProperties( ReflectionProperty::IS_PUBLIC )
);

Getting the properties by get_object_vars()

/** lists: `fooPublic`, `fooDynamic` */
var_export(
    get_object_vars( $object )
);

/** lists: `fooPrivate`, `fooPublic`, `fooDynamic` */
var_export(
    $object->getProperties()
);

Summary

  • ReflectionClass::getProperties()
    • cannot fetch dynamically assigned properties
  • ReflectionObject::getProperties()
    • can fetch dynamically assigned properties
  • ReflectionClass::getProperties() and ReflectionObject::getProperties() both
    • can fetch static properties
    • can fetch properties no matter their defined access scope
    • both can be called with a filter
  • get_object_vars()
    • can fetch dynamically assigned properties
    • cannot fetch static properties
    • cannot fetch properties the calling scope does not have access to, which is absolutely correct in the way access modification is meant to work in OOP
0

精彩评论

暂无评论...
验证码 换一张
取 消