PHP反射——这是错误还是预期行为?

PHP反射——这是错误还是预期行为?,php,reflection,Php,Reflection,我正在创建一个使用ReflectionProperty的类,并且得到了奇怪的结果 本质上,调用$reflectionProperty->getType()->getName()返回一些完全无关数组的值。它在看似随机的条件下做到这一点 见下文: //这将用作类型提示属性。 类DummyClass{ 公共函数构造($arr){ } //以反射方式设置其属性值的类 类基类{ /**@var ReflectionProperty[]*/ 私有静态$publicProps=[]; /** *获取具体类的公

我正在创建一个使用ReflectionProperty的类,并且得到了奇怪的结果

本质上,调用
$reflectionProperty->getType()->getName()
返回一些完全无关数组的值。它在看似随机的条件下做到这一点

见下文:

//这将用作类型提示属性。
类DummyClass{
公共函数构造($arr){
}
//以反射方式设置其属性值的类
类基类{
/**@var ReflectionProperty[]*/
私有静态$publicProps=[];
/**
*获取具体类的公共ReflectionProperties,并缓存它们
*因此,我们不需要为这个具体类再次执行反射。
*
*@return ReflectionProperty[]
*@ReflectionException
*/
私有函数getPublicProps(){
如果(!static::$publicProps){
$concreteClass=get_class($this);
静态::$publicProps=(新的ReflectionClass($concreteClass))
->getProperties(ReflectionProperty::是公共的);
}
返回静态::$publicProps;
}
/**
*对于此类中的每个公共属性,将值设置为$propArr中的相应值。
*
*@param$propArr
*@ReflectionException
*/
公共功能构造($propArr){
$concreteClass=get_class($this);
echo“创建$concreteClass的新实例
”; foreach($this->getPublicProps()作为$prop){ //获取要设置的属性、其类和要传递给构造函数的值 $propName=$prop->getName(); $propClass=$prop->getType()->getName(); $propValue=$propArr[$propName]; $propValueStr=var_导出($propValue,true); //打印出我们要做的事情,断言$propClass是正确的。 echo“--设置:->$propName=new$propClass($propValueStr)
”; 断言($propClass==“DummyClass”、“$propClass!==DummyClass”); //创建实例并分配它 $refClass=新的ReflectionClass($propClass); $this->$propName=$refClass->newInstanceArgs([$propValue]); } } } //上述类的一个具体实现,只有1个类型提示属性。 类ConcreteClass扩展了基类{ 公共DummyClass$prop1; } //应该创建ConcreteClass的实例 //使用->prop1=新的DummyClass([“foo”=>“abc123”]) $testArr1=[ “prop1”=>[“foo”=>“abc123”] ]; //应该创建ConcreteClass的实例 //使用->prop1=新的DummyClass([“boo”=>“abc123def456”]) $testArr2=[ “prop1”=>[“boo”=>“abc123def456”] ]; $tc1=新混凝土等级($testArr1); echo“创建了TestClass1…

”; $tc2=新混凝土等级($testArr2); echo“创建了TestClass2…

”; 死亡
结果是:

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
的值是
abc123def456
——这是如何发生的

更多的古怪

  • 将“abc123def456”的值更改为“12345678”即可工作
  • 将“abc123def456”的值更改为“123456789”将不起作用
  • 省略var_export(),它将起作用。(不过,在其他情况下,它可能仍会断裂)

我的直觉告诉我这是一个PHP错误,但我可能做错了什么,和/或这可能会被记录在某个地方。我想澄清一下,因为目前我唯一可靠的解决方案是不缓存反映的$publicProps。这导致每次我创建一个新的
ConcreteClass
,都会不必要地调用
ReflectionClass->getProperties()
,这是我想要避免的。

结果发现这是PHP中的一个错误:

此处的最小复制:


在7.4.9中已修复:

php7.4.9运行良好,因此错误已修复。查看变更日志-是的,看起来像个bug。我试着在Windows上玩我的本地7.4.0,得到了非常奇怪的结果,不仅是奇怪的结果,而且如果我多次执行,脚本也会崩溃。我甚至将您的代码缩减为,但如果您运行两次,它仍然会使该版本的PHP崩溃(现在还不确定这是否相关,lol)。@u_mulder谢谢。确实是这个bug,这里的复制量很小:。如果你提供一个答案,我会接受。你可以回答你自己的问题,我只是用小提琴运行了你的代码,并看到了行为改变的版本。)@u_mulder好的,可以。我不知道礼节是什么,我想你可能想在回答问题时得到分数。再次感谢。