1--TEST--
2Scalar type strict mode
3--SKIPIF--
4<?php if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); ?>
5--FILE--
6<?php
7declare(strict_types=1);
8
9$functions = [
10    'int' => function (int $i) { return $i; },
11    'float' => function (float $f) { return $f; },
12    'string' => function (string $s) { return $s; },
13    'bool' => function (bool $b) { return $b; }
14];
15
16class StringCapable {
17    public function __toString() {
18        return "foobar";
19    }
20}
21
22$values = [
23    1,
24    "1",
25    1.0,
26    1.5,
27    "1a",
28    "a",
29    "",
30    PHP_INT_MAX,
31    NAN,
32    TRUE,
33    FALSE,
34    NULL,
35    [],
36    new StdClass,
37    new StringCapable,
38    fopen("data:text/plain,foobar", "r")
39];
40
41foreach ($functions as $type => $function) {
42    echo PHP_EOL, "Testing '$type' type:", PHP_EOL;
43    foreach ($values as $value) {
44        echo PHP_EOL . "*** Trying ";
45        var_dump($value);
46        try {
47            var_dump($function($value));
48        } catch (TypeError $e) {
49            echo "*** Caught " . $e->getMessage() . PHP_EOL;
50        }
51    }
52}
53
54echo PHP_EOL . "Done";
55?>
56--EXPECTF--
57Testing 'int' type:
58
59*** Trying int(1)
60int(1)
61
62*** Trying string(1) "1"
63*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
64
65*** Trying float(1)
66*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
67
68*** Trying float(1.5)
69*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
70
71*** Trying string(2) "1a"
72*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
73
74*** Trying string(1) "a"
75*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
76
77*** Trying string(0) ""
78*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
79
80*** Trying int(2147483647)
81int(2147483647)
82
83*** Trying float(NAN)
84*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
85
86*** Trying bool(true)
87*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, true given, called in %s on line %d
88
89*** Trying bool(false)
90*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, false given, called in %s on line %d
91
92*** Trying NULL
93*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
94
95*** Trying array(0) {
96}
97*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, array given, called in %s on line %d
98
99*** Trying object(stdClass)#5 (0) {
100}
101*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, stdClass given, called in %s on line %d
102
103*** Trying object(StringCapable)#6 (0) {
104}
105*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, StringCapable given, called in %s on line %d
106
107*** Trying resource(5) of type (stream)
108*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, resource given, called in %s on line %d
109
110Testing 'float' type:
111
112*** Trying int(1)
113float(1)
114
115*** Trying string(1) "1"
116*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
117
118*** Trying float(1)
119float(1)
120
121*** Trying float(1.5)
122float(1.5)
123
124*** Trying string(2) "1a"
125*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
126
127*** Trying string(1) "a"
128*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
129
130*** Trying string(0) ""
131*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
132
133*** Trying int(2147483647)
134float(2147483647)
135
136*** Trying float(NAN)
137float(NAN)
138
139*** Trying bool(true)
140*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, true given, called in %s on line %d
141
142*** Trying bool(false)
143*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, false given, called in %s on line %d
144
145*** Trying NULL
146*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
147
148*** Trying array(0) {
149}
150*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, array given, called in %s on line %d
151
152*** Trying object(stdClass)#5 (0) {
153}
154*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, stdClass given, called in %s on line %d
155
156*** Trying object(StringCapable)#6 (0) {
157}
158*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, StringCapable given, called in %s on line %d
159
160*** Trying resource(5) of type (stream)
161*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, resource given, called in %s on line %d
162
163Testing 'string' type:
164
165*** Trying int(1)
166*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
167
168*** Trying string(1) "1"
169string(1) "1"
170
171*** Trying float(1)
172*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
173
174*** Trying float(1.5)
175*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
176
177*** Trying string(2) "1a"
178string(2) "1a"
179
180*** Trying string(1) "a"
181string(1) "a"
182
183*** Trying string(0) ""
184string(0) ""
185
186*** Trying int(2147483647)
187*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
188
189*** Trying float(NAN)
190*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
191
192*** Trying bool(true)
193*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, true given, called in %s on line %d
194
195*** Trying bool(false)
196*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, false given, called in %s on line %d
197
198*** Trying NULL
199*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
200
201*** Trying array(0) {
202}
203*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, array given, called in %s on line %d
204
205*** Trying object(stdClass)#5 (0) {
206}
207*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, stdClass given, called in %s on line %d
208
209*** Trying object(StringCapable)#6 (0) {
210}
211*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, StringCapable given, called in %s on line %d
212
213*** Trying resource(5) of type (stream)
214*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, resource given, called in %s on line %d
215
216Testing 'bool' type:
217
218*** Trying int(1)
219*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
220
221*** Trying string(1) "1"
222*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
223
224*** Trying float(1)
225*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
226
227*** Trying float(1.5)
228*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
229
230*** Trying string(2) "1a"
231*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
232
233*** Trying string(1) "a"
234*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
235
236*** Trying string(0) ""
237*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
238
239*** Trying int(2147483647)
240*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
241
242*** Trying float(NAN)
243*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
244
245*** Trying bool(true)
246bool(true)
247
248*** Trying bool(false)
249bool(false)
250
251*** Trying NULL
252*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
253
254*** Trying array(0) {
255}
256*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, array given, called in %s on line %d
257
258*** Trying object(stdClass)#5 (0) {
259}
260*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, stdClass given, called in %s on line %d
261
262*** Trying object(StringCapable)#6 (0) {
263}
264*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, StringCapable given, called in %s on line %d
265
266*** Trying resource(5) of type (stream)
267*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, resource given, called in %s on line %d
268
269Done
270