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