1--TEST-- 2Behavior of union type checks (strict) 3--FILE-- 4<?php 5 6declare(strict_types=1); 7 8function dump($value) { 9 if (is_object($value)) { 10 return 'new ' . get_class($value); 11 } 12 if ($value === INF) { 13 return 'INF'; 14 } 15 return json_encode($value, JSON_PRESERVE_ZERO_FRACTION); 16} 17 18function test(string $type, array $values) { 19 $alignment = 16; 20 21 echo "\nType $type:\n"; 22 $fn = eval("return function($type \$arg) { return \$arg; };"); 23 foreach ($values as $value) { 24 echo str_pad(dump($value), $alignment), ' => '; 25 26 try { 27 error_clear_last(); 28 $value = @$fn($value); 29 echo dump($value); 30 if ($e = error_get_last()) { 31 echo ' (', $e['message'], ')'; 32 } 33 } catch (TypeError $e) { 34 $msg = $e->getMessage(); 35 $msg = strstr($msg, ', called in', true); 36 $msg = str_replace('{closure}(): Argument #1 ($arg)', 'Argument ...', $msg); 37 echo $msg; 38 } 39 echo "\n"; 40 } 41} 42 43class WithToString { 44 public function __toString() { 45 return "__toString()"; 46 } 47} 48 49$values = [ 50 42, 42.0, INF, "42", "42.0", "42x", "x", "", 51 true, false, null, [], new stdClass, new WithToString, 52]; 53test('int|float', $values); 54test('int|float|false', $values); 55test('int|float|bool', $values); 56test('int|bool', $values); 57test('int|string|null', $values); 58test('string|bool', $values); 59test('float|array', $values); 60test('string|array', $values); 61test('bool|array', $values); 62 63?> 64--EXPECT-- 65Type int|float: 6642 => 42 6742.0 => 42.0 68INF => INF 69"42" => Argument ... must be of type int|float, string given 70"42.0" => Argument ... must be of type int|float, string given 71"42x" => Argument ... must be of type int|float, string given 72"x" => Argument ... must be of type int|float, string given 73"" => Argument ... must be of type int|float, string given 74true => Argument ... must be of type int|float, bool given 75false => Argument ... must be of type int|float, bool given 76null => Argument ... must be of type int|float, null given 77[] => Argument ... must be of type int|float, array given 78new stdClass => Argument ... must be of type int|float, stdClass given 79new WithToString => Argument ... must be of type int|float, WithToString given 80 81Type int|float|false: 8242 => 42 8342.0 => 42.0 84INF => INF 85"42" => Argument ... must be of type int|float|false, string given 86"42.0" => Argument ... must be of type int|float|false, string given 87"42x" => Argument ... must be of type int|float|false, string given 88"x" => Argument ... must be of type int|float|false, string given 89"" => Argument ... must be of type int|float|false, string given 90true => Argument ... must be of type int|float|false, bool given 91false => false 92null => Argument ... must be of type int|float|false, null given 93[] => Argument ... must be of type int|float|false, array given 94new stdClass => Argument ... must be of type int|float|false, stdClass given 95new WithToString => Argument ... must be of type int|float|false, WithToString given 96 97Type int|float|bool: 9842 => 42 9942.0 => 42.0 100INF => INF 101"42" => Argument ... must be of type int|float|bool, string given 102"42.0" => Argument ... must be of type int|float|bool, string given 103"42x" => Argument ... must be of type int|float|bool, string given 104"x" => Argument ... must be of type int|float|bool, string given 105"" => Argument ... must be of type int|float|bool, string given 106true => true 107false => false 108null => Argument ... must be of type int|float|bool, null given 109[] => Argument ... must be of type int|float|bool, array given 110new stdClass => Argument ... must be of type int|float|bool, stdClass given 111new WithToString => Argument ... must be of type int|float|bool, WithToString given 112 113Type int|bool: 11442 => 42 11542.0 => Argument ... must be of type int|bool, float given 116INF => Argument ... must be of type int|bool, float given 117"42" => Argument ... must be of type int|bool, string given 118"42.0" => Argument ... must be of type int|bool, string given 119"42x" => Argument ... must be of type int|bool, string given 120"x" => Argument ... must be of type int|bool, string given 121"" => Argument ... must be of type int|bool, string given 122true => true 123false => false 124null => Argument ... must be of type int|bool, null given 125[] => Argument ... must be of type int|bool, array given 126new stdClass => Argument ... must be of type int|bool, stdClass given 127new WithToString => Argument ... must be of type int|bool, WithToString given 128 129Type int|string|null: 13042 => 42 13142.0 => Argument ... must be of type string|int|null, float given 132INF => Argument ... must be of type string|int|null, float given 133"42" => "42" 134"42.0" => "42.0" 135"42x" => "42x" 136"x" => "x" 137"" => "" 138true => Argument ... must be of type string|int|null, bool given 139false => Argument ... must be of type string|int|null, bool given 140null => null 141[] => Argument ... must be of type string|int|null, array given 142new stdClass => Argument ... must be of type string|int|null, stdClass given 143new WithToString => Argument ... must be of type string|int|null, WithToString given 144 145Type string|bool: 14642 => Argument ... must be of type string|bool, int given 14742.0 => Argument ... must be of type string|bool, float given 148INF => Argument ... must be of type string|bool, float given 149"42" => "42" 150"42.0" => "42.0" 151"42x" => "42x" 152"x" => "x" 153"" => "" 154true => true 155false => false 156null => Argument ... must be of type string|bool, null given 157[] => Argument ... must be of type string|bool, array given 158new stdClass => Argument ... must be of type string|bool, stdClass given 159new WithToString => Argument ... must be of type string|bool, WithToString given 160 161Type float|array: 16242 => 42.0 16342.0 => 42.0 164INF => INF 165"42" => Argument ... must be of type array|float, string given 166"42.0" => Argument ... must be of type array|float, string given 167"42x" => Argument ... must be of type array|float, string given 168"x" => Argument ... must be of type array|float, string given 169"" => Argument ... must be of type array|float, string given 170true => Argument ... must be of type array|float, bool given 171false => Argument ... must be of type array|float, bool given 172null => Argument ... must be of type array|float, null given 173[] => [] 174new stdClass => Argument ... must be of type array|float, stdClass given 175new WithToString => Argument ... must be of type array|float, WithToString given 176 177Type string|array: 17842 => Argument ... must be of type array|string, int given 17942.0 => Argument ... must be of type array|string, float given 180INF => Argument ... must be of type array|string, float given 181"42" => "42" 182"42.0" => "42.0" 183"42x" => "42x" 184"x" => "x" 185"" => "" 186true => Argument ... must be of type array|string, bool given 187false => Argument ... must be of type array|string, bool given 188null => Argument ... must be of type array|string, null given 189[] => [] 190new stdClass => Argument ... must be of type array|string, stdClass given 191new WithToString => Argument ... must be of type array|string, WithToString given 192 193Type bool|array: 19442 => Argument ... must be of type array|bool, int given 19542.0 => Argument ... must be of type array|bool, float given 196INF => Argument ... must be of type array|bool, float given 197"42" => Argument ... must be of type array|bool, string given 198"42.0" => Argument ... must be of type array|bool, string given 199"42x" => Argument ... must be of type array|bool, string given 200"x" => Argument ... must be of type array|bool, string given 201"" => Argument ... must be of type array|bool, string given 202true => true 203false => false 204null => Argument ... must be of type array|bool, null given 205[] => [] 206new stdClass => Argument ... must be of type array|bool, stdClass given 207new WithToString => Argument ... must be of type array|bool, WithToString given 208