Description
Description
I'm testing some edge cases with my code and started tracing a problem down to PHP itself. It turns out that assigning the minimum value of a 64 bit signed integer as a literal value ( -9223372036854775808) to a variable is not recognized as an integer. However, minimum value + 1 (-9223372036854775807) is recognized as an integer. In addition, the PHP_INT_MIN constant with the same value is recognized as an integer. Something is going on with the interpretation of numeric literals for only this specific value.
Furthermore, if I start with assigning a variable the minimum value - 1 (ie $value = -9223372036854775807 -1), then the minimum 64 bit signed value is correctly interpreted as an integer.
The following code:
<?php
error_reporting(E_ALL);
function foo(int $value) {
return "Yes!";
}
echo "PHP Version: ".PHP_VERSION."<br>";
echo "Minimum value: ".PHP_INT_MIN."<br>"; // -9223372036854775808
echo "is_int: ".is_int(PHP_INT_MIN)."<br>";
echo "gettype: ".gettype(PHP_INT_MIN)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', PHP_INT_MIN))[1])."<br>";
try {
echo "function worked: " . foo(PHP_INT_MIN)."<br>";
} catch (Exception $e) {
echo "function failed: ".$e->getMessage()."<br>";
}
echo "<br>";
echo "PHP_INT_MIN assignment to variable<br>";
$value = PHP_INT_MIN;
echo "number: PHP_INT_MIN<br>";
echo "variable: ".$value."<br>";
echo "is_int: ".is_int($value)."<br>";
echo "gettype: ".gettype($value)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
echo "function type declaration failed: ".$e->getMessage()."<br>";
}
echo "<br>";
echo "Hard-coded/literal assignment of -9223372036854775808 to variable<br>";
$value = -9223372036854775808;
echo "number: -9223372036854775808<br>";
echo "variable: ".$value."<br>"; // -9.2233720368548E+18 ?
echo "is_int: ".is_int($value)."<br>"; // false?
echo "gettype: ".gettype($value)."<br>"; // double?
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
echo "function type declaration failed: ".$e->getMessage()."<br>";
}
echo "<br>";
$value = -9223372036854775807;
echo "test: minimum signed int64 + 1<br>";
echo "number: -9223372036854775807<br>";
echo "variable: ".$value."<br>";
echo "is_int: ".is_int($value)."<br>";
echo "gettype: ".gettype($value)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
echo "function type declaration failed: ".$e->getMessage()."<br>";
}
echo "<br>";
$value = -9223372036854775807 - 1;
echo "test: minimum signed (int64 + 1) - 1<br>";
echo "number: -9223372036854775808<br>";
echo "variable: ".$value."<br>";
echo "is_int: ".is_int($value)."<br>";
echo "gettype: ".gettype($value)."<br>";
echo "binary: 0x". strtoupper(unpack('H*', pack('J', $value))[1])."<br>";
try {
echo "function type declaration passed: " . foo($value)."<br>";
} catch (Exception $e) {
echo "function type declaration failed: ".$e->getMessage()."<br>";
}
?>
Resulted in this output:
PHP Version: 8.3.6
Minimum value: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function worked: Yes!
PHP_INT_MIN assignment to variable
number: PHP_INT_MIN
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!
Hard-coded/literal assignment of -9223372036854775808 to variable
number: -9223372036854775808
variable: -9.2233720368548E+18
is_int:
gettype: double
binary: 0x8000000000000000
function type declaration passed: Yes!
test: minimum signed int64 + 1
number: -9223372036854775807
variable: -9223372036854775807
is_int: 1
gettype: integer
binary: 0x8000000000000001
function type declaration passed: Yes!
test: minimum signed (int64 + 1) - 1
number: -9223372036854775808
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!
But I expected this output instead:
PHP Version: 8.3.6
Minimum value: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function worked: Yes!
PHP_INT_MIN assignment to variable
number: PHP_INT_MIN
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!
Hard-coded/literal assignment of -9223372036854775808 to variable
number: -9223372036854775808
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!
test: minimum signed int64 + 1
number: -9223372036854775807
variable: -9223372036854775807
is_int: 1
gettype: integer
binary: 0x8000000000000001
function type declaration passed: Yes!
test: minimum signed (int64 + 1) - 1
number: -9223372036854775808
variable: -9223372036854775808
is_int: 1
gettype: integer
binary: 0x8000000000000000
function type declaration passed: Yes!
PHP Version
8.3.6
Operating System
No response