You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过反射区分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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:45:54