PHP中如何获取未初始化的类型化属性的声明类型?
解决方案
通过PHP反射API读取类的属性声明类型即可,不需要访问属性本身,不会触发未初始化报错。
修改后的代码示例:
class User { public int $id = 0; public string $code; public string $name; public function __construct(array $data) { // 生成当前类的反射实例,仅需实例化一次 $classRef = new ReflectionClass(self::class); foreach ($data as $key => $val) { // 跳过类中不存在的属性 if (!$classRef->hasProperty($key)) { continue; } $propRef = $classRef->getProperty($key); // 获取属性的声明类型 $propType = $propRef->getType(); // 处理标量命名类型的转换逻辑 if ($propType instanceof ReflectionNamedType && !$propType->isBuiltin() === false) { settype($val, $propType->getName()); } // 赋值 $this->$key = $val; } } }
原代码报错原因
gettype() 是运行时函数,需要先读取属性的当前值才能返回其类型,而PHP不允许访问未初始化的类型化属性,因此直接触发致命错误。
反射API读取的是类的结构定义信息,不需要属性已经初始化即可拿到声明的类型规则,完美适配你的需求。
优化建议
- 可以将反射结果全局缓存,避免每次实例化类都重新生成反射对象,提升性能
- 如果你的属性用到可空类型、联合类型,需要额外判断
$propType的实例类型(ReflectionUnionType/ReflectionIntersectionType),自定义对应的转换逻辑 - 如果有对象类型的属性,需要额外添加对象实例化的处理逻辑,不能直接用
settype转换
内容的提问来源于stack exchange,提问作者Chud37
相关产品推荐
相关产品推荐

