1--TEST-- 2Behavior of union type checks (weak) 3--FILE-- 4<?php 5 6function dump($value) { 7 if (is_object($value)) { 8 return 'new ' . get_class($value); 9 } 10 if ($value === INF) { 11 return 'INF'; 12 } 13 return json_encode($value, JSON_PRESERVE_ZERO_FRACTION); 14} 15 16function test(string $type, array $values) { 17 $alignment = 16; 18 19 echo "\nType $type:\n"; 20 $fn = eval("return function($type \$arg) { return \$arg; };"); 21 foreach ($values as $value) { 22 echo str_pad(dump($value), $alignment), ' => '; 23 24 try { 25 error_clear_last(); 26 $value = @$fn($value); 27 echo dump($value); 28 if ($e = error_get_last()) { 29 echo ' (', $e['message'], ')'; 30 } 31 } catch (TypeError $e) { 32 $msg = $e->getMessage(); 33 $msg = strstr($msg, ', called in', true); 34 $msg = str_replace('{closure}(): Argument #1 ($arg)', 'Argument ...', $msg); 35 echo $msg; 36 } 37 echo "\n"; 38 } 39} 40 41class WithToString { 42 public function __toString() { 43 return "__toString()"; 44 } 45} 46 47$values = [ 48 42, 42.0, INF, "42", "42.0", "42x", "x", "", 49 true, false, null, [], new stdClass, new WithToString, 50]; 51test('int|float', $values); 52test('int|float|false', $values); 53test('int|float|bool', $values); 54test('int|bool', $values); 55test('int|string|null', $values); 56test('string|bool', $values); 57test('float|array', $values); 58test('string|array', $values); 59test('bool|array', $values); 60 61?> 62--EXPECT-- 63Type int|float: 6442 => 42 6542.0 => 42.0 66INF => INF 67"42" => 42 68"42.0" => 42.0 69"42x" => Argument ... must be of type int|float, string given 70"x" => Argument ... must be of type int|float, string given 71"" => Argument ... must be of type int|float, string given 72true => 1 73false => 0 74null => Argument ... must be of type int|float, null given 75[] => Argument ... must be of type int|float, array given 76new stdClass => Argument ... must be of type int|float, stdClass given 77new WithToString => Argument ... must be of type int|float, WithToString given 78 79Type int|float|false: 8042 => 42 8142.0 => 42.0 82INF => INF 83"42" => 42 84"42.0" => 42.0 85"42x" => Argument ... must be of type int|float|false, string given 86"x" => Argument ... must be of type int|float|false, string given 87"" => Argument ... must be of type int|float|false, string given 88true => 1 89false => false 90null => Argument ... must be of type int|float|false, null given 91[] => Argument ... must be of type int|float|false, array given 92new stdClass => Argument ... must be of type int|float|false, stdClass given 93new WithToString => Argument ... must be of type int|float|false, WithToString given 94 95Type int|float|bool: 9642 => 42 9742.0 => 42.0 98INF => INF 99"42" => 42 100"42.0" => 42.0 101"42x" => true 102"x" => true 103"" => false 104true => true 105false => false 106null => Argument ... must be of type int|float|bool, null given 107[] => Argument ... must be of type int|float|bool, array given 108new stdClass => Argument ... must be of type int|float|bool, stdClass given 109new WithToString => Argument ... must be of type int|float|bool, WithToString given 110 111Type int|bool: 11242 => 42 11342.0 => 42 114INF => true 115"42" => 42 116"42.0" => 42 117"42x" => true 118"x" => true 119"" => false 120true => true 121false => false 122null => Argument ... must be of type int|bool, null given 123[] => Argument ... must be of type int|bool, array given 124new stdClass => Argument ... must be of type int|bool, stdClass given 125new WithToString => Argument ... must be of type int|bool, WithToString given 126 127Type int|string|null: 12842 => 42 12942.0 => 42 130INF => "INF" 131"42" => "42" 132"42.0" => "42.0" 133"42x" => "42x" 134"x" => "x" 135"" => "" 136true => 1 137false => 0 138null => null 139[] => Argument ... must be of type string|int|null, array given 140new stdClass => Argument ... must be of type string|int|null, stdClass given 141new WithToString => "__toString()" 142 143Type string|bool: 14442 => "42" 14542.0 => "42" 146INF => "INF" 147"42" => "42" 148"42.0" => "42.0" 149"42x" => "42x" 150"x" => "x" 151"" => "" 152true => true 153false => false 154null => Argument ... must be of type string|bool, null given 155[] => Argument ... must be of type string|bool, array given 156new stdClass => Argument ... must be of type string|bool, stdClass given 157new WithToString => "__toString()" 158 159Type float|array: 16042 => 42.0 16142.0 => 42.0 162INF => INF 163"42" => 42.0 164"42.0" => 42.0 165"42x" => Argument ... must be of type array|float, string given 166"x" => Argument ... must be of type array|float, string given 167"" => Argument ... must be of type array|float, string given 168true => 1.0 169false => 0.0 170null => Argument ... must be of type array|float, null given 171[] => [] 172new stdClass => Argument ... must be of type array|float, stdClass given 173new WithToString => Argument ... must be of type array|float, WithToString given 174 175Type string|array: 17642 => "42" 17742.0 => "42" 178INF => "INF" 179"42" => "42" 180"42.0" => "42.0" 181"42x" => "42x" 182"x" => "x" 183"" => "" 184true => "1" 185false => "" 186null => Argument ... must be of type array|string, null given 187[] => [] 188new stdClass => Argument ... must be of type array|string, stdClass given 189new WithToString => "__toString()" 190 191Type bool|array: 19242 => true 19342.0 => true 194INF => true 195"42" => true 196"42.0" => true 197"42x" => true 198"x" => true 199"" => false 200true => true 201false => false 202null => Argument ... must be of type array|bool, null given 203[] => [] 204new stdClass => Argument ... must be of type array|bool, stdClass given 205new WithToString => Argument ... must be of type array|bool, WithToString given 206