From 5f80c8784192130102ed8ccc9cde62472b494f2c Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 21 Jul 2025 15:38:34 +0200 Subject: [PATCH 1/2] Fix '?' in ReflectionNamedType::getName() from ReflectionProperty::getSettableType() Fixes GH-19187 --- ext/reflection/php_reflection.c | 6 +++--- ext/reflection/tests/gh19187.phpt | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 ext/reflection/tests/gh19187.phpt diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index f79d8a5181dda..778a7db9a8fec 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6517,7 +6517,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) /* Get-only virtual property can never be written to. */ if (prop->hooks && (prop->flags & ZEND_ACC_VIRTUAL) && !prop->hooks[ZEND_PROPERTY_HOOK_SET]) { zend_type never_type = ZEND_TYPE_INIT_CODE(IS_NEVER, 0, 0); - reflection_type_factory(never_type, return_value, 0); + reflection_type_factory(never_type, return_value, 1); return; } @@ -6527,7 +6527,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) if (!ZEND_TYPE_IS_SET(arg_info->type)) { RETURN_NULL(); } - reflection_type_factory(arg_info->type, return_value, 0); + reflection_type_factory(arg_info->type, return_value, 1); return; } @@ -6535,7 +6535,7 @@ ZEND_METHOD(ReflectionProperty, getSettableType) if (!ZEND_TYPE_IS_SET(ref->prop->type)) { RETURN_NULL(); } - reflection_type_factory(ref->prop->type, return_value, 0); + reflection_type_factory(ref->prop->type, return_value, 1); } /* {{{ Returns whether property has a type */ diff --git a/ext/reflection/tests/gh19187.phpt b/ext/reflection/tests/gh19187.phpt new file mode 100644 index 0000000000000..b59c13da70c63 --- /dev/null +++ b/ext/reflection/tests/gh19187.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-19187: ReflectionNamedType::getName() should not include nullable type +--FILE-- + $value; + } +} + +$reflProp = new ReflectionProperty(Foo::class, 'bar'); +echo $reflProp->getType()->getName(), "\n"; +echo $reflProp->getSettableType()->getName(), "\n"; + +?> +--EXPECT-- +string +string From 5fc1394ad46baa03544821a42b691e05a97eb4aa Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 21 Jul 2025 17:12:41 +0200 Subject: [PATCH 2/2] Expand tests --- ext/reflection/tests/gh19187.phpt | 47 +++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/ext/reflection/tests/gh19187.phpt b/ext/reflection/tests/gh19187.phpt index b59c13da70c63..35a684aa6af73 100644 --- a/ext/reflection/tests/gh19187.phpt +++ b/ext/reflection/tests/gh19187.phpt @@ -3,17 +3,54 @@ GH-19187: ReflectionNamedType::getName() should not include nullable type --FILE-- $value; + } + public string|null $b { set(string|null $value) => $value; } + public string|null $c { + get => $this->c; + } } -$reflProp = new ReflectionProperty(Foo::class, 'bar'); -echo $reflProp->getType()->getName(), "\n"; -echo $reflProp->getSettableType()->getName(), "\n"; +foreach ((new ReflectionClass(C::class))->getProperties() as $r) { + $type = $r->getType(); + echo $type, "\n"; + echo $type->getName(), "\n"; + var_dump($type->allowsNull()); + echo "\n"; + + $settableType = $r->getSettableType(); + echo $settableType, "\n"; + echo $settableType->getName(), "\n"; + var_dump($settableType->allowsNull()); + echo "\n"; +} ?> --EXPECT-- +?string string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string +string +bool(true) + +?string string +bool(true)