Skip to content

Add ReflectionProperty::isDynamic as a more obvious alternative to ReflectionProperty::isDefault #15754

Closed
@jnvsor

Description

@jnvsor

ReflectionProperty::isDefault is a non-obvious name, and since the documentation doesn't seem to mention "Default properties" anywhere else its opposite isDynamic would be nice to have


Original post remains to document my shame

Description

With 8.4 we're getting reflection support for dynamic properties:

<?php

$v = new stdClass();
$v->item1 = 1;
$v->item2 = 2;

$reflector = new ReflectionObject($v);
var_dump($reflector->getProperties());

class X {
    public string $y = 'z';
}

$v = new X();
$v->item1 = 1;
$v->item2 = 2;

$reflector = new ReflectionObject($v);
var_dump($reflector->getProperties());
array(2) {
  [0]=>
  object(ReflectionProperty)#3 (2) {
    ["name"]=>
    string(5) "item1"
    ["class"]=>
    string(8) "stdClass"
  }
  [1]=>
  object(ReflectionProperty)#4 (2) {
    ["name"]=>
    string(5) "item2"
    ["class"]=>
    string(8) "stdClass"
  }
}
array(3) {
  [0]=>
  object(ReflectionProperty)#2 (2) {
    ["name"]=>
    string(1) "y"
    ["class"]=>
    string(1) "X"
  }
  [1]=>
  object(ReflectionProperty)#1 (2) {
    ["name"]=>
    string(5) "item1"
    ["class"]=>
    string(1) "X"
  }
  [2]=>
  object(ReflectionProperty)#5 (2) {
    ["name"]=>
    string(5) "item2"
    ["class"]=>
    string(1) "X"
  }
}

Unfortunately there doesn't seem to be any way to distinguish them. Both reflection and the stub file show no methods to see if a property is dynamically added, and there are no new constants to use with getProperties.

While you can tell the difference by comparing ReflectionObject->getProperties with ReflectionClass->getProperties it's rather cumbersome:

function getPropNameArrayFormat($prop) {
    if ($prop->isPublic()) {
        return $prop->getName();
    } elseif ($prop->isProtected()) {
        return "\0*\0".$prop->getName();
    } elseif ($prop->isPrivate()) {
        return "\0".$prop->getDeclaringClass()->getName()."\0".$prop->getName();
    }
}

$reflector = new ReflectionObject($v);
$objprops = $reflector->getProperties();
var_dump($objprops);

$reflector = new ReflectionClass(get_class($v));
$classprops = $reflector->getProperties();
var_dump($classprops);

$objprops = array_map(getPropNameArrayFormat(...), $objprops);
$classprops = array_map(getPropNameArrayFormat(...), $classprops);

var_dump(array_diff($objprops, $classprops));

Can we please have an isDynamic method or something?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions