1--TEST-- 2Union types in reflection 3--FILE-- 4<?php 5 6function dumpType(ReflectionUnionType $rt) { 7 echo "Type $rt:\n"; 8 echo "Allows null: " . ($rt->allowsNull() ? "true" : "false") . "\n"; 9 foreach ($rt->getTypes() as $type) { 10 echo " Name: " . $type->getName() . "\n"; 11 echo " String: " . (string) $type . "\n"; 12 echo " Allows Null: " . ($type->allowsNull() ? "true" : "false") . "\n"; 13 } 14} 15 16function test1(): X|Y|int|float|false|null { } 17function test2(): X|iterable|bool { } 18 19class Test { 20 public X|Y|int $prop; 21} 22 23dumpType((new ReflectionFunction('test1'))->getReturnType()); 24dumpType((new ReflectionFunction('test2'))->getReturnType()); 25 26$rc = new ReflectionClass(Test::class); 27$rp = $rc->getProperty('prop'); 28dumpType($rp->getType()); 29 30/* Force CE resolution of the property type */ 31 32class x {} 33$test = new Test; 34$test->prop = new x; 35 36$rp = $rc->getProperty('prop'); 37dumpType($rp->getType()); 38 39class y {} 40$test->prop = new y; 41 42$rp = $rc->getProperty('prop'); 43dumpType($rp->getType()); 44 45?> 46--EXPECT-- 47Type X|Y|int|float|false|null: 48Allows null: true 49 Name: X 50 String: X 51 Allows Null: false 52 Name: Y 53 String: Y 54 Allows Null: false 55 Name: int 56 String: int 57 Allows Null: false 58 Name: float 59 String: float 60 Allows Null: false 61 Name: false 62 String: false 63 Allows Null: false 64 Name: null 65 String: null 66 Allows Null: true 67Type X|iterable|bool: 68Allows null: false 69 Name: X 70 String: X 71 Allows Null: false 72 Name: iterable 73 String: iterable 74 Allows Null: false 75 Name: bool 76 String: bool 77 Allows Null: false 78Type X|Y|int: 79Allows null: false 80 Name: X 81 String: X 82 Allows Null: false 83 Name: Y 84 String: Y 85 Allows Null: false 86 Name: int 87 String: int 88 Allows Null: false 89Type X|Y|int: 90Allows null: false 91 Name: X 92 String: X 93 Allows Null: false 94 Name: Y 95 String: Y 96 Allows Null: false 97 Name: int 98 String: int 99 Allows Null: false 100Type X|Y|int: 101Allows null: false 102 Name: X 103 String: X 104 Allows Null: false 105 Name: Y 106 String: Y 107 Allows Null: false 108 Name: int 109 String: int 110 Allows Null: false 111