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_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR' 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 Stringable { 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 Stringable, 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) 74int(1) 75*** Trying string(2) "1a" 76E_NOTICE: A non well formed numeric value encountered on line %d 77int(1) 78*** Trying string(1) "a" 79*** Caught Return value of {closure}() must be of the type integer, string returned in %s on line %d 80*** Trying string(0) "" 81*** Caught Return value of {closure}() must be of the type integer, string returned in %s on line %d 82*** Trying int(2147483647) 83int(2147483647) 84*** Trying float(NAN) 85*** Caught Return value of {closure}() must be of the type integer, float returned in %s on line %d 86*** Trying bool(true) 87int(1) 88*** Trying bool(false) 89int(0) 90*** Trying NULL 91*** Caught Return value of {closure}() must be of the type integer, null returned in %s on line %d 92*** Trying array(0) { 93} 94*** Caught Return value of {closure}() must be of the type integer, array returned in %s on line %d 95*** Trying object(stdClass)#6 (0) { 96} 97*** Caught Return value of {closure}() must be of the type integer, object returned in %s on line %d 98*** Trying object(Stringable)#7 (0) { 99} 100*** Caught Return value of {closure}() must be of the type integer, object returned in %s on line %d 101*** Trying resource(5) of type (stream) 102*** Caught Return value of {closure}() must be of the type integer, 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" 114E_NOTICE: A non well formed numeric value encountered on line %d 115float(1) 116*** Trying string(1) "a" 117*** Caught Return value of {closure}() must be of the type float, string returned in %s on line %d 118*** Trying string(0) "" 119*** Caught Return value of {closure}() must be of the type float, string returned in %s on line %d 120*** Trying int(2147483647) 121float(2147483647) 122*** Trying float(NAN) 123float(NAN) 124*** Trying bool(true) 125float(1) 126*** Trying bool(false) 127float(0) 128*** Trying NULL 129*** Caught Return value of {closure}() must be of the type float, null returned in %s on line %d 130*** Trying array(0) { 131} 132*** Caught Return value of {closure}() must be of the type float, array returned in %s on line %d 133*** Trying object(stdClass)#6 (0) { 134} 135*** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d 136*** Trying object(Stringable)#7 (0) { 137} 138*** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d 139*** Trying resource(5) of type (stream) 140*** Caught Return value of {closure}() must be of the type float, resource returned in %s on line %d 141 142Testing 'string' type: 143*** Trying int(1) 144string(1) "1" 145*** Trying string(1) "1" 146string(1) "1" 147*** Trying float(1) 148string(1) "1" 149*** Trying float(1.5) 150string(3) "1.5" 151*** Trying string(2) "1a" 152string(2) "1a" 153*** Trying string(1) "a" 154string(1) "a" 155*** Trying string(0) "" 156string(0) "" 157*** Trying int(2147483647) 158string(10) "2147483647" 159*** Trying float(NAN) 160string(3) "NAN" 161*** Trying bool(true) 162string(1) "1" 163*** Trying bool(false) 164string(0) "" 165*** Trying NULL 166*** Caught Return value of {closure}() must be of the type string, null returned in %s on line %d 167*** Trying array(0) { 168} 169*** Caught Return value of {closure}() must be of the type string, array returned in %s on line %d 170*** Trying object(stdClass)#6 (0) { 171} 172*** Caught Return value of {closure}() must be of the type string, object returned in %s on line %d 173*** Trying object(Stringable)#7 (0) { 174} 175string(6) "foobar" 176*** Trying resource(5) of type (stream) 177*** Caught Return value of {closure}() must be of the type string, resource returned in %s on line %d 178 179Testing 'bool' type: 180*** Trying int(1) 181bool(true) 182*** Trying string(1) "1" 183bool(true) 184*** Trying float(1) 185bool(true) 186*** Trying float(1.5) 187bool(true) 188*** Trying string(2) "1a" 189bool(true) 190*** Trying string(1) "a" 191bool(true) 192*** Trying string(0) "" 193bool(false) 194*** Trying int(2147483647) 195bool(true) 196*** Trying float(NAN) 197bool(true) 198*** Trying bool(true) 199bool(true) 200*** Trying bool(false) 201bool(false) 202*** Trying NULL 203*** Caught Return value of {closure}() must be of the type boolean, null returned in %s on line %d 204*** Trying array(0) { 205} 206*** Caught Return value of {closure}() must be of the type boolean, array returned in %s on line %d 207*** Trying object(stdClass)#6 (0) { 208} 209*** Caught Return value of {closure}() must be of the type boolean, object returned in %s on line %d 210*** Trying object(Stringable)#7 (0) { 211} 212*** Caught Return value of {closure}() must be of the type boolean, object returned in %s on line %d 213*** Trying resource(5) of type (stream) 214*** Caught Return value of {closure}() must be of the type boolean, resource returned in %s on line %d 215 216Done 217