This RFC from Ilija Tovilo and Larry Garfield adds two methods to ReflectionProperty, isReadable() and isWritable(). They tell you whether a property can be read or written from a given scope in your code.

Why it helps

isPublic() only tells you whether a property has the public modifier. Before PHP 8.1, that was enough to know outside code could write to it. Then readonly properties arrived, which can be public but still not writable from outside. PHP 8.4 added asymmetric visibility, like public private(set), which splits read and write access even further. That left no simple way to ask "can I read this?" or "can I write this?" at runtime.

How it looks

class ReflectionProperty
{
    public function isReadable(?string $scope, ?object $object = null): bool {}

    public function isWritable(?string $scope, ?object $object = null): bool {}
}

$scope is the place you're asking from. Pass null for global scope, like a plain function, or pass a class name to ask whether a method on that class could do it. self::class means the class you're currently in.

$object is optional. Leave it out and PHP only looks at how the property is declared. Pass an object and PHP also checks its current state, such as whether a readonly property has already been initialized or whether the property was unset().

The methods also handle a few special cases:

  • Hooks. A virtual property, one with no backing value, is readable only if it has a get hook and writable only if it has a set hook.
  • Magic methods. If a read would fall through to __get(), PHP calls __isset() when it exists and uses its answer, and reports readable when it doesn't. If a write would fall through to __set(), it reports writable.
  • Static properties work too, but passing an object for one is an error.

The RFC is clear that a true answer isn't a guarantee, since a hook can still throw an exception. Some built-in classes also have properties that can't be modified without using readonly or private(set), and these methods won't detect them.

What it means for existing code

Nothing breaks, because the RFC only adds two methods.

The vote

It passed with 27 votes in favor, none against and 3 abstaining, well above the two-thirds it needed. Voting closed on February 2, 2026, and the page says it's implemented in PHP 8.6.