如何通过反射区分PHP中仅含Setter的可读写与只写属性?
如何通过反射区分PHP中仅定义Setter的两种属性差异
先看你提供的代码:
class Test { public string $Foo { set => strtoupper($value); } public string $Bar { set {} } } $test = new Test; $test->Foo = 'foo'; $test->Bar = 'bar'; echo $test->Foo; echo $test->Bar; // Error: Property Test::$Bar is write-only
这段代码里,$Foo和$Bar都只定义了Setter,但$Foo能正常读取,$Bar是只写属性。核心原因是:PHP 8.1+的属性访问器语法中,当你用箭头函数形式的简洁Setter(set => ...)时,PHP会自动为该属性生成一个默认的Getter;而用空大括号的Setter(set {})时,不会生成默认Getter,导致属性变为只写。
用反射机制区分的方法
可以通过两种方式实现:
方式一:检查对应Getter方法是否存在
PHP会把属性的Getter命名为get{PropertyName}(首字母大写),对于自动生成默认Getter的属性,反射时能找到对应的方法;只写属性则找不到。
$reflectionClass = new ReflectionClass(Test::class); // 检查$Foo属性 echo "Foo属性是否可读:" . ($reflectionClass->hasMethod('getFoo') ? '是' : '否') . PHP_EOL; // 检查$Bar属性 echo "Bar属性是否可读:" . ($reflectionClass->hasMethod('getBar') ? '是' : '否') . PHP_EOL;
输出结果:
Foo属性是否可读:是 Bar属性是否可读:否
方式二:直接使用isReadable()方法
ReflectionProperty类的isReadable()方法会自动识别属性是否具备读取能力,内部已封装了对访问器的判断逻辑:
$reflectionClass = new ReflectionClass(Test::class); $fooProperty = $reflectionClass->getProperty('Foo'); $barProperty = $reflectionClass->getProperty('Bar'); echo "Foo属性是否可读:" . ($fooProperty->isReadable() ? '是' : '否') . PHP_EOL; echo "Bar属性是否可读:" . ($barProperty->isReadable() ? '是' : '否') . PHP_EOL;
输出结果和方式一完全一致。
内容的提问来源于stack exchange,提问作者Jan Sverre
相关产品推荐
相关产品推荐

