Skip to content

Commit c2f70e6

Browse files
Add nullable (?type) and non-nullable (!type) cast operators
1 parent 27948dc commit c2f70e6

40 files changed

+3814
-632
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Cast operators chaining and precedence
3+
--FILE--
4+
<?php
5+
6+
var_dump((?string) (?int) "123");
7+
var_dump((!float) (!int) "456");
8+
9+
var_dump((?int) null ?? 100);
10+
var_dump(((?int) null) ?? 100);
11+
12+
var_dump((!int) "5" + (!int) "10");
13+
var_dump((!int) "20" * 2);
14+
15+
?>
16+
--EXPECT--
17+
string(3) "123"
18+
float(456)
19+
int(100)
20+
int(100)
21+
int(15)
22+
int(40)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Cast operators with complex expressions
3+
--FILE--
4+
<?php
5+
6+
var_dump((?int) (1 + 2));
7+
var_dump((!int) (3 * 4));
8+
9+
function getValue() {
10+
return "123";
11+
}
12+
13+
var_dump((?int) getValue());
14+
var_dump((!int) getValue());
15+
16+
$x = null;
17+
$result = ((?int) $x) ?? 10;
18+
var_dump($result);
19+
20+
$arr = [
21+
(?int) null,
22+
(?int) "789",
23+
(!string) 123
24+
];
25+
var_dump($arr);
26+
27+
?>
28+
--EXPECT--
29+
int(3)
30+
int(12)
31+
int(123)
32+
int(123)
33+
int(10)
34+
array(3) {
35+
[0]=>
36+
NULL
37+
[1]=>
38+
int(789)
39+
[2]=>
40+
string(3) "123"
41+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Cast operators with numeric strings
3+
--FILE--
4+
<?php
5+
6+
var_dump((?int) "123");
7+
var_dump((!int) "123");
8+
var_dump((?float) "45.67");
9+
var_dump((!float) "45.67");
10+
11+
var_dump((?int) " 89 ");
12+
var_dump((!int) " 89 ");
13+
14+
try {
15+
var_dump((?int) "123abc");
16+
} catch (TypeError $e) {
17+
echo "Caught: " . $e->getMessage() . "\n";
18+
}
19+
20+
try {
21+
var_dump((!float) "12.5xyz");
22+
} catch (TypeError $e) {
23+
echo "Caught: " . $e->getMessage() . "\n";
24+
}
25+
26+
// Completely non-numeric - should fail
27+
try {
28+
var_dump((?int) "hello");
29+
} catch (TypeError $e) {
30+
echo "Caught: " . $e->getMessage() . "\n";
31+
}
32+
33+
?>
34+
--EXPECT--
35+
int(123)
36+
int(123)
37+
float(45.67)
38+
float(45.67)
39+
int(89)
40+
int(89)
41+
Caught: Cannot cast string to int
42+
Caught: Cannot cast string to float
43+
Caught: Cannot cast string to int
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
Nullable and non-null casts ignore strict_types declaration
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
var_dump((?int) "123");
8+
var_dump((!int) "456");
9+
10+
try {
11+
var_dump((?int) "123aze");
12+
} catch (TypeError $e) {
13+
echo "Caught: " . $e->getMessage() . "\n";
14+
}
15+
16+
try {
17+
var_dump((!int) "abc");
18+
} catch (TypeError $e) {
19+
echo "Caught: " . $e->getMessage() . "\n";
20+
}
21+
22+
// Null handling
23+
var_dump((?int) null);
24+
try {
25+
var_dump((!int) null);
26+
} catch (TypeError $e) {
27+
echo "Caught: " . $e->getMessage() . "\n";
28+
}
29+
30+
?>
31+
--EXPECT--
32+
int(123)
33+
int(456)
34+
Caught: Cannot cast string to int
35+
Caught: Cannot cast string to int
36+
NULL
37+
Caught: Cannot cast null to int
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Cast operators with variables
3+
--FILE--
4+
<?php
5+
6+
$nullVar = null;
7+
$intVar = 42;
8+
$stringVar = "123";
9+
$invalidStringVar = "abc";
10+
11+
var_dump((?int) $nullVar);
12+
var_dump((?int) $intVar);
13+
var_dump((?int) $stringVar);
14+
15+
try {
16+
var_dump((!int) $nullVar);
17+
} catch (TypeError $e) {
18+
echo "Caught TypeError for null\n";
19+
}
20+
21+
var_dump((!int) $intVar);
22+
var_dump((!int) $stringVar);
23+
24+
try {
25+
var_dump((!int) $invalidStringVar);
26+
} catch (TypeError $e) {
27+
echo "Caught TypeError for invalid string\n";
28+
}
29+
30+
?>
31+
--EXPECT--
32+
NULL
33+
int(42)
34+
int(123)
35+
Caught TypeError for null
36+
int(42)
37+
int(123)
38+
Caught TypeError for invalid string
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Non-null array cast: basic functionality
3+
--FILE--
4+
<?php
5+
6+
var_dump((!array) [1, 2, 3]);
7+
8+
class Foo {
9+
public $bar = "baz";
10+
}
11+
var_dump((!array) new Foo());
12+
13+
?>
14+
--EXPECT--
15+
array(3) {
16+
[0]=>
17+
int(1)
18+
[1]=>
19+
int(2)
20+
[2]=>
21+
int(3)
22+
}
23+
array(1) {
24+
["bar"]=>
25+
string(3) "baz"
26+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Non-null array cast: null throws TypeError
3+
--FILE--
4+
<?php
5+
6+
try {
7+
var_dump((!array) null);
8+
echo "Should have thrown TypeError\n";
9+
} catch (TypeError $e) {
10+
echo "TypeError: " . $e->getMessage() . "\n";
11+
}
12+
13+
?>
14+
--EXPECT--
15+
TypeError: Cannot cast null to array
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Non-null bool cast: basic functionality
3+
--FILE--
4+
<?php
5+
6+
var_dump((!bool) true);
7+
var_dump((!bool) false);
8+
9+
var_dump((!bool) 0);
10+
var_dump((!bool) 1);
11+
var_dump((!bool) 42);
12+
13+
var_dump((!bool) "");
14+
var_dump((!bool) "0");
15+
var_dump((!bool) "hello");
16+
17+
class SimpleObject {}
18+
$obj = new SimpleObject();
19+
20+
try {
21+
var_dump((!bool) $obj);
22+
} catch (TypeError $e) {
23+
echo "TypeError: " . $e->getMessage() . "\n";
24+
}
25+
26+
?>
27+
--EXPECT--
28+
bool(true)
29+
bool(false)
30+
bool(false)
31+
bool(true)
32+
bool(true)
33+
bool(false)
34+
bool(false)
35+
bool(true)
36+
TypeError: Cannot cast SimpleObject to bool
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
Non-null bool cast: null throws TypeError
3+
--FILE--
4+
<?php
5+
6+
try {
7+
var_dump((!bool) null);
8+
echo "Should have thrown TypeError\n";
9+
} catch (TypeError $e) {
10+
echo "TypeError: " . $e->getMessage() . "\n";
11+
}
12+
13+
?>
14+
--EXPECT--
15+
TypeError: Cannot cast null to bool
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
Non-null float cast: basic functionality
3+
--FILE--
4+
<?php
5+
6+
var_dump((!float) 12.34);
7+
8+
var_dump((!float) 56);
9+
10+
var_dump((!float) "78.9");
11+
12+
var_dump((!float) true);
13+
var_dump((!float) false);
14+
15+
class SimpleObject {}
16+
$obj = new SimpleObject();
17+
18+
try {
19+
var_dump((!float) $obj);
20+
} catch (TypeError $e) {
21+
echo "TypeError: " . $e->getMessage() . "\n";
22+
}
23+
24+
?>
25+
--EXPECT--
26+
float(12.34)
27+
float(56)
28+
float(78.9)
29+
float(1)
30+
float(0)
31+
TypeError: Cannot cast SimpleObject to float

0 commit comments

Comments
 (0)