1--TEST-- 2Return scalar type basics 3--SKIPIF-- 4<?php if (PHP_INT_SIZE != 8) die("skip this test is for 64bit platform only"); ?> 5--FILE-- 6<?php 7 8$errnames = [ 9 E_NOTICE => 'E_NOTICE', 10 E_WARNING => 'E_WARNING', 11]; 12set_error_handler(function (int $errno, string $errmsg, string $file, int $line) use ($errnames) { 13 echo "$errnames[$errno]: $errmsg on line $line\n"; 14 return true; 15}); 16 17$functions = [ 18 'int' => function ($i): int { return $i; }, 19 'float' => function ($f): float { return $f; }, 20 'string' => function ($s): string { return $s; }, 21 'bool' => function ($b): bool { return $b; } 22]; 23 24class Stringable { 25 public function __toString() { 26 return "foobar"; 27 } 28} 29 30$values = [ 31 1, 32 "1", 33 1.0, 34 1.5, 35 "1a", 36 "a", 37 "", 38 PHP_INT_MAX, 39 NAN, 40 TRUE, 41 FALSE, 42 NULL, 43 [], 44 new StdClass, 45 new Stringable, 46 fopen("data:text/plain,foobar", "r") 47]; 48 49foreach ($functions as $type => $function) { 50 echo PHP_EOL, "Testing '$type' type:", PHP_EOL; 51 foreach ($values as $value) { 52 echo "*** Trying "; 53 var_dump($value); 54 try { 55 var_dump($function($value)); 56 } catch (TypeError $e) { 57 echo "*** Caught ", $e->getMessage(), " in ", $e->getFile(), " on line ", $e->getLine(), PHP_EOL; 58 } 59 } 60} 61 62echo PHP_EOL . "Done"; 63?> 64--EXPECTF-- 65Testing 'int' type: 66*** Trying int(1) 67int(1) 68*** Trying string(1) "1" 69int(1) 70*** Trying float(1) 71int(1) 72*** Trying float(1.5) 73int(1) 74*** Trying string(2) "1a" 75E_NOTICE: A non well formed numeric value encountered on line %d 76int(1) 77*** Trying string(1) "a" 78*** Caught Return value of {closure}() must be of the type int, string returned in %s on line %d 79*** Trying string(0) "" 80*** Caught Return value of {closure}() must be of the type int, string returned in %s on line %d 81*** Trying int(9223372036854775807) 82int(9223372036854775807) 83*** Trying float(NAN) 84*** Caught Return value of {closure}() must be of the type int, float returned in %s on line %d 85*** Trying bool(true) 86int(1) 87*** Trying bool(false) 88int(0) 89*** Trying NULL 90*** Caught Return value of {closure}() must be of the type int, null returned in %s on line %d 91*** Trying array(0) { 92} 93*** Caught Return value of {closure}() must be of the type int, array returned in %s on line %d 94*** Trying object(stdClass)#6 (0) { 95} 96*** Caught Return value of {closure}() must be of the type int, object returned in %s on line %d 97*** Trying object(Stringable)#7 (0) { 98} 99*** Caught Return value of {closure}() must be of the type int, object returned in %s on line %d 100*** Trying resource(5) of type (stream) 101*** Caught Return value of {closure}() must be of the type int, resource returned in %s on line %d 102 103Testing 'float' type: 104*** Trying int(1) 105float(1) 106*** Trying string(1) "1" 107float(1) 108*** Trying float(1) 109float(1) 110*** Trying float(1.5) 111float(1.5) 112*** Trying string(2) "1a" 113E_NOTICE: A non well formed numeric value encountered on line %d 114float(1) 115*** Trying string(1) "a" 116*** Caught Return value of {closure}() must be of the type float, string returned in %s on line %d 117*** Trying string(0) "" 118*** Caught Return value of {closure}() must be of the type float, string returned in %s on line %d 119*** Trying int(9223372036854775807) 120float(9.2233720368548E+18) 121*** Trying float(NAN) 122float(NAN) 123*** Trying bool(true) 124float(1) 125*** Trying bool(false) 126float(0) 127*** Trying NULL 128*** Caught Return value of {closure}() must be of the type float, null returned in %s on line %d 129*** Trying array(0) { 130} 131*** Caught Return value of {closure}() must be of the type float, array returned in %s on line %d 132*** Trying object(stdClass)#6 (0) { 133} 134*** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d 135*** Trying object(Stringable)#7 (0) { 136} 137*** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d 138*** Trying resource(5) of type (stream) 139*** Caught Return value of {closure}() must be of the 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(9223372036854775807) 157string(19) "9223372036854775807" 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 Return value of {closure}() must be of the type string, null returned in %s on line %d 166*** Trying array(0) { 167} 168*** Caught Return value of {closure}() must be of the type string, array returned in %s on line %d 169*** Trying object(stdClass)#6 (0) { 170} 171*** Caught Return value of {closure}() must be of the type string, object returned in %s on line %d 172*** Trying object(Stringable)#7 (0) { 173} 174string(6) "foobar" 175*** Trying resource(5) of type (stream) 176*** Caught Return value of {closure}() must be of the 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(9223372036854775807) 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 Return value of {closure}() must be of the type bool, null returned in %s on line %d 203*** Trying array(0) { 204} 205*** Caught Return value of {closure}() must be of the type bool, array returned in %s on line %d 206*** Trying object(stdClass)#6 (0) { 207} 208*** Caught Return value of {closure}() must be of the type bool, object returned in %s on line %d 209*** Trying object(Stringable)#7 (0) { 210} 211*** Caught Return value of {closure}() must be of the type bool, object returned in %s on line %d 212*** Trying resource(5) of type (stream) 213*** Caught Return value of {closure}() must be of the type bool, resource returned in %s on line %d 214 215Done 216