我正在创建一个使用ReflectionProperty的类,并且得到了奇怪的结果。
本质上,调用.basket-summary {
min-height: 15rem;
min-width: 10rem;
padding-bottom: 1rem;
margin-top: 10rem;
}
返回的是一些完全不相关的数组的值。它是在看似随机的条件下完成的。
见下文:
$reflectionProperty->getType()->getName()
结果:
// this will be used as a type hinted property.
class DummyClass {
public function __construct($arr) {}
}
// a class that sets its property values reflectively
class BaseClass {
/** @var ReflectionProperty[] */
private static $publicProps = [];
/**
* Gets public ReflectionProperties of the concrete class, and caches them
* so we do not need to perform reflection again for this concrete class.
*
* @return ReflectionProperty[]
* @throws ReflectionException
*/
private function getPublicProps(){
if (!static::$publicProps) {
$concreteClass = get_class($this);
static::$publicProps = (new ReflectionClass($concreteClass))
->getProperties(ReflectionProperty::IS_PUBLIC);
}
return static::$publicProps;
}
/**
* For each public property in this class set value to the corresponding value from $propArr.
*
* @param $propArr
* @throws ReflectionException
*/
public function __construct($propArr) {
$concreteClass = get_class($this);
echo "Creating new instance of $concreteClass<br>";
foreach ($this->getPublicProps() as $prop) {
// get which property to set, its class, and value to pass to constructor
$propName = $prop->getName();
$propClass = $prop->getType()->getName();
$propValue = $propArr[$propName];
$propValueStr = var_export($propValue, true);
// print out what we are about to do, and assert $propClass is correct.
echo "---Setting: ->$propName = new $propClass($propValueStr)<br>";
assert($propClass === "DummyClass", "$propClass !== DummyClass");
// create the instance and assign it
$refClass = new ReflectionClass($propClass);
$this->$propName = $refClass->newInstanceArgs([$propValue]);
}
}
}
// a concrete implementation of the above class, with only 1 type hinted property.
class ConcreteClass extends BaseClass {
public DummyClass $prop1;
}
// should create an instance of ConcreteClass
// with ->prop1 = new DummyClass(["foo"=>"abc123"])
$testArr1 = [
"prop1" => ["foo" => "abc123"]
];
// should create an instance of ConcreteClass
// with ->prop1 = new DummyClass(["boo"=>"abc123def456"])
$testArr2 = [
"prop1" => ["boo" => "abc123def456"]
];
$tc1 = new ConcreteClass($testArr1);
echo "Created TestClass1...<br><br>";
$tc2 = new ConcreteClass($testArr2);
echo "Created TestClass2...<br><br>";
die;
请注意,Creating new instance of ConcreteClass
Setting: ->prop1 = new DummyClass(array ( 'foo' => 'abc123', ))
Created TestClass1...
Creating new instance of ConcreteClass
Setting: ->prop1 = new abc123def456(array ( 'boo' => 'abc123def456', ))
Error: assert(): abc123def456 !== DummyClass failed
的值为$propClass
,这是怎么发生的?
更古怪
我的直觉告诉我这是一个PHP错误,但我可能做错了,和/或可能在某处记录了该错误。我想澄清一下,因为到目前为止,我唯一可靠的解决方案是不缓存反映的$ publicProps。这样一来,每次我创建新的abc123def456
时都会避免不必要地调用ReflectionClass->getProperties()
。
答案 0 :(得分:1)
结果证明这是PHP中的错误:https://bugs.php.net/bug.php?id=79820
此处的复制量最少:https://3v4l.org/kchfm
已在7.4.9中修复:https://www.php.net/ChangeLog-7.php#7.4.9