1--TEST-- 2Return scalar type basics 3--SKIPIF-- 4<?php if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); ?> 5--FILE-- 6<?php 7 8$errnames = [ 9 E_NOTICE => 'E_NOTICE', 10 E_WARNING => 'E_WARNING', 11 E_DEPRECATED => 'E_DEPRECATED', 12]; 13set_error_handler(function (int $errno, string $errmsg, string $file, int $line) use ($errnames) { 14 echo "$errnames[$errno]: $errmsg on line $line\n"; 15 return true; 16}); 17 18$functions = [ 19 'int' => function ($i): int { return $i; }, 20 'float' => function ($f): float { return $f; }, 21 'string' => function ($s): string { return $s; }, 22 'bool' => function ($b): bool { return $b; } 23]; 24 25class StringCapable { 26 public function __toString() { 27 return "foobar"; 28 } 29} 30 31$values = [ 32 1, 33 "1", 34 1.0, 35 1.5, 36 "1a", 37 "a", 38 "", 39 PHP_INT_MAX, 40 NAN, 41 TRUE, 42 FALSE, 43 NULL, 44 [], 45 new StdClass, 46 new StringCapable, 47 fopen("data:text/plain,foobar", "r") 48]; 49 50foreach ($functions as $type => $function) { 51 echo PHP_EOL, "Testing '$type' type:", PHP_EOL; 52 foreach ($values as $value) { 53 echo "*** Trying "; 54 var_dump($value); 55 try { 56 var_dump($function($value)); 57 } catch (TypeError $e) { 58 echo "*** Caught ", $e->getMessage(), " in ", $e->getFile(), " on line ", $e->getLine(), PHP_EOL; 59 } 60 } 61} 62 63echo PHP_EOL . "Done"; 64?> 65--EXPECTF-- 66Testing 'int' type: 67*** Trying int(1) 68int(1) 69*** Trying string(1) "1" 70int(1) 71*** Trying float(1) 72int(1) 73*** Trying float(1.5) 74E_DEPRECATED: Implicit conversion from float 1.5 to int loses precision on line %d 75int(1) 76*** Trying string(2) "1a" 77*** Caught {closure}(): Return value must be of type int, string returned in %s on line %d 78*** Trying string(1) "a" 79*** Caught {closure}(): Return value must be of type int, string returned in %s on line %d 80*** Trying string(0) "" 81*** Caught {closure}(): Return value must be of type int, string returned in %s on line %d 82*** Trying int(2147483647) 83int(2147483647) 84*** Trying float(NAN) 85*** Caught {closure}(): Return value must be of type int, float returned in %s on line %d 86*** Trying bool(true) 87int(1) 88*** Trying bool(false) 89int(0) 90*** Trying NULL 91*** Caught {closure}(): Return value must be of type int, null returned in %s on line %d 92*** Trying array(0) { 93} 94*** Caught {closure}(): Return value must be of type int, array returned in %s on line %d 95*** Trying object(stdClass)#6 (0) { 96} 97*** Caught {closure}(): Return value must be of type int, stdClass returned in %s on line %d 98*** Trying object(StringCapable)#7 (0) { 99} 100*** Caught {closure}(): Return value must be of type int, StringCapable returned in %s on line %d 101*** Trying resource(5) of type (stream) 102*** Caught {closure}(): Return value must be of type int, resource returned in %s on line %d 103 104Testing 'float' type: 105*** Trying int(1) 106float(1) 107*** Trying string(1) "1" 108float(1) 109*** Trying float(1) 110float(1) 111*** Trying float(1.5) 112float(1.5) 113*** Trying string(2) "1a" 114*** Caught {closure}(): Return value must be of type float, string returned in %s on line %d 115*** Trying string(1) "a" 116*** Caught {closure}(): Return value must be of type float, string returned in %s on line %d 117*** Trying string(0) "" 118*** Caught {closure}(): Return value must be of type float, string returned in %s on line %d 119*** Trying int(2147483647) 120float(2147483647) 121*** Trying float(NAN) 122float(NAN) 123*** Trying bool(true) 124float(1) 125*** Trying bool(false) 126float(0) 127*** Trying NULL 128*** Caught {closure}(): Return value must be of type float, null returned in %s on line %d 129*** Trying array(0) { 130} 131*** Caught {closure}(): Return value must be of type float, array returned in %s on line %d 132*** Trying object(stdClass)#6 (0) { 133} 134*** Caught {closure}(): Return value must be of type float, stdClass returned in %s on line %d 135*** Trying object(StringCapable)#7 (0) { 136} 137*** Caught {closure}(): Return value must be of type float, StringCapable returned in %s on line %d 138*** Trying resource(5) of type (stream) 139*** Caught {closure}(): Return value must be of type float, resource returned in %s on line %d 140 141Testing 'string' type: 142*** Trying int(1) 143string(1) "1" 144*** Trying string(1) "1" 145string(1) "1" 146*** Trying float(1) 147string(1) "1" 148*** Trying float(1.5) 149string(3) "1.5" 150*** Trying string(2) "1a" 151string(2) "1a" 152*** Trying string(1) "a" 153string(1) "a" 154*** Trying string(0) "" 155string(0) "" 156*** Trying int(2147483647) 157string(10) "2147483647" 158*** Trying float(NAN) 159string(3) "NAN" 160*** Trying bool(true) 161string(1) "1" 162*** Trying bool(false) 163string(0) "" 164*** Trying NULL 165*** Caught {closure}(): Return value must be of type string, null returned in %s on line %d 166*** Trying array(0) { 167} 168*** Caught {closure}(): Return value must be of type string, array returned in %s on line %d 169*** Trying object(stdClass)#6 (0) { 170} 171*** Caught {closure}(): Return value must be of type string, stdClass returned in %s on line %d 172*** Trying object(StringCapable)#7 (0) { 173} 174string(6) "foobar" 175*** Trying resource(5) of type (stream) 176*** Caught {closure}(): Return value must be of type string, resource returned in %s on line %d 177 178Testing 'bool' type: 179*** Trying int(1) 180bool(true) 181*** Trying string(1) "1" 182bool(true) 183*** Trying float(1) 184bool(true) 185*** Trying float(1.5) 186bool(true) 187*** Trying string(2) "1a" 188bool(true) 189*** Trying string(1) "a" 190bool(true) 191*** Trying string(0) "" 192bool(false) 193*** Trying int(2147483647) 194bool(true) 195*** Trying float(NAN) 196bool(true) 197*** Trying bool(true) 198bool(true) 199*** Trying bool(false) 200bool(false) 201*** Trying NULL 202*** Caught {closure}(): Return value must be of type bool, null returned in %s on line %d 203*** Trying array(0) { 204} 205*** Caught {closure}(): Return value must be of type bool, array returned in %s on line %d 206*** Trying object(stdClass)#6 (0) { 207} 208*** Caught {closure}(): Return value must be of type bool, stdClass returned in %s on line %d 209*** Trying object(StringCapable)#7 (0) { 210} 211*** Caught {closure}(): Return value must be of type bool, StringCapable returned in %s on line %d 212*** Trying resource(5) of type (stream) 213*** Caught {closure}(): Return value must be of type bool, resource returned in %s on line %d 214 215Done 216