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--
62Testing 'int' type:
63
64*** Trying int(1)
65int(1)
66
67*** Trying string(1) "1"
68int(1)
69
70*** Trying float(1)
71int(1)
72
73*** Trying float(1.5)
74int(1)
75
76*** Trying string(2) "1a"
77E_NOTICE: A non well formed numeric value encountered on line %d
78int(1)
79
80*** Trying string(1) "a"
81*** Caught Argument 1 passed to {closure}() must be of the type int, string given, called in %s on line %d
82
83*** Trying string(0) ""
84*** Caught Argument 1 passed to {closure}() must be of the type int, string given, called in %s on line %d
85
86*** Trying int(%d)
87int(%d)
88
89*** Trying float(NAN)
90*** Caught Argument 1 passed to {closure}() must be of the type int, float given, called in %s on line %d
91
92*** Trying bool(true)
93int(1)
94
95*** Trying bool(false)
96int(0)
97
98*** Trying NULL
99*** Caught Argument 1 passed to {closure}() must be of the type int, null given, called in %s on line %d
100
101*** Trying array(0) {
102}
103*** Caught Argument 1 passed to {closure}() must be of the type int, array given, called in %s on line %d
104
105*** Trying object(stdClass)#%s (0) {
106}
107*** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d
108
109*** Trying object(Stringable)#%s (0) {
110}
111*** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d
112
113*** Trying resource(%d) of type (stream)
114*** Caught Argument 1 passed to {closure}() must be of the type int, resource given, called in %s on line %d
115
116Testing 'float' type:
117
118*** Trying int(1)
119float(1)
120
121*** Trying string(1) "1"
122float(1)
123
124*** Trying float(1)
125float(1)
126
127*** Trying float(1.5)
128float(1.5)
129
130*** Trying string(2) "1a"
131E_NOTICE: A non well formed numeric value encountered on line %d
132float(1)
133
134*** Trying string(1) "a"
135*** Caught Argument 1 passed to {closure}() must be of the type float, string given, called in %s on line %d
136
137*** Trying string(0) ""
138*** Caught Argument 1 passed to {closure}() must be of the type float, string given, called in %s on line %d
139
140*** Trying int(%d)
141float(%s)
142
143*** Trying float(NAN)
144float(NAN)
145
146*** Trying bool(true)
147float(1)
148
149*** Trying bool(false)
150float(0)
151
152*** Trying NULL
153*** Caught Argument 1 passed to {closure}() must be of the type float, null given, called in %s on line %d
154
155*** Trying array(0) {
156}
157*** Caught Argument 1 passed to {closure}() must be of the type float, array given, called in %s on line %d
158
159*** Trying object(stdClass)#%s (0) {
160}
161*** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d
162
163*** Trying object(Stringable)#%s (0) {
164}
165*** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d
166
167*** Trying resource(%d) of type (stream)
168*** Caught Argument 1 passed to {closure}() must be of the type float, resource given, called in %s on line %d
169
170Testing 'string' type:
171
172*** Trying int(1)
173string(1) "1"
174
175*** Trying string(1) "1"
176string(1) "1"
177
178*** Trying float(1)
179string(1) "1"
180
181*** Trying float(1.5)
182string(3) "1.5"
183
184*** Trying string(2) "1a"
185string(2) "1a"
186
187*** Trying string(1) "a"
188string(1) "a"
189
190*** Trying string(0) ""
191string(0) ""
192
193*** Trying int(%d)
194string(%d) "%d"
195
196*** Trying float(NAN)
197string(3) "NAN"
198
199*** Trying bool(true)
200string(1) "1"
201
202*** Trying bool(false)
203string(0) ""
204
205*** Trying NULL
206*** Caught Argument 1 passed to {closure}() must be of the type string, null given, called in %s on line %d
207
208*** Trying array(0) {
209}
210*** Caught Argument 1 passed to {closure}() must be of the type string, array given, called in %s on line %d
211
212*** Trying object(stdClass)#%s (0) {
213}
214*** Caught Argument 1 passed to {closure}() must be of the type string, object given, called in %s on line %d
215
216*** Trying object(Stringable)#%s (0) {
217}
218string(6) "foobar"
219
220*** Trying resource(%d) of type (stream)
221*** Caught Argument 1 passed to {closure}() must be of the type string, resource given, called in %s on line %d
222
223Testing 'bool' type:
224
225*** Trying int(1)
226bool(true)
227
228*** Trying string(1) "1"
229bool(true)
230
231*** Trying float(1)
232bool(true)
233
234*** Trying float(1.5)
235bool(true)
236
237*** Trying string(2) "1a"
238bool(true)
239
240*** Trying string(1) "a"
241bool(true)
242
243*** Trying string(0) ""
244bool(false)
245
246*** Trying int(%d)
247bool(true)
248
249*** Trying float(NAN)
250bool(true)
251
252*** Trying bool(true)
253bool(true)
254
255*** Trying bool(false)
256bool(false)
257
258*** Trying NULL
259*** Caught Argument 1 passed to {closure}() must be of the type bool, null given, called in %s on line %d
260
261*** Trying array(0) {
262}
263*** Caught Argument 1 passed to {closure}() must be of the type bool, array given, called in %s on line %d
264
265*** Trying object(stdClass)#%s (0) {
266}
267*** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d
268
269*** Trying object(Stringable)#%s (0) {
270}
271*** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d
272
273*** Trying resource(%d) of type (stream)
274*** Caught Argument 1 passed to {closure}() must be of the type bool, resource given, called in %s on line %d
275
276Done
277