Category
Regression · php-src-strict · language · Reflection · pillar 4
Problem
ReflectionType::__toString() (via (string)$type) diverges from Zend for two cases that already parse/compile:
- DNF parentheses — Zend keeps grouping parens around an intersection in a union; VM drops them.
int|null normalization — Zend stringifies int|null as ?int; VM keeps int|null (?int shorthand still matches).
Verified 2026-07-25 (host Zend PHP 8.2.32 vs php bin/vm.php):
| Repro |
Zend 8.2+ |
VM |
(string) of (Traversable&Countable)|array param |
(Traversable&Countable)|array |
Traversable&Countable|array (parens missing) |
(string) of int|null param |
?int |
int|null |
(string) of ?int param |
?int |
?int (same) |
php-src reference
PHP implementation target
- Reflection type
__toString / name rendering in ext/reflection (PHP) — emit Zend-identical DNF parentheses and ?T for single-named |null unions
- PHP-in-PHP; no new
runtime/*.c
Repro
./script/docker-exec.sh -- bash -lc 'cat > /tmp/reflect_type_str.php <<'"'"'PHP'"'"'
<?php
function f((Traversable&Countable)|array $x) {}
function g(int|null $x) {}
function h(?int $x) {}
echo (string)(new ReflectionFunction("f"))->getParameters()[0]->getType(), "\n";
echo (string)(new ReflectionFunction("g"))->getParameters()[0]->getType(), "\n";
echo (string)(new ReflectionFunction("h"))->getParameters()[0]->getType(), "\n";
PHP
php bin/vm.php /tmp/reflect_type_str.php
# expect:
# (Traversable&Countable)|array
# ?int
# ?int
Done when
Category
Regression· php-src-strict · language · Reflection · pillar 4Problem
ReflectionType::__toString()(via(string)$type) diverges from Zend for two cases that already parse/compile:int|nullnormalization — Zend stringifiesint|nullas?int; VM keepsint|null(?intshorthand still matches).Verified 2026-07-25 (host Zend PHP 8.2.32 vs
php bin/vm.php):(string)of(Traversable&Countable)|arrayparam(Traversable&Countable)|arrayTraversable&Countable|array(parens missing)(string)ofint|nullparam?intint|null(string)of?intparam?int?int(same)php-src reference
ext/reflection/php_reflection.c—ReflectionType/ union / intersection / DNF stringification__toStringshape parityPHP implementation target
__toString/ name rendering inext/reflection(PHP) — emit Zend-identical DNF parentheses and?Tfor single-named|nullunionsruntime/*.cRepro
Done when
int|null(andnull|int) stringifies as?int.phptundertest/compliance/cases/reflection/