[RFC] On the need of a `is_int_string` ?
| From: | Vincent Langlet | Date: | Thu, 15 Aug 2024 15:42:02 +0000 |
| Subject: | [RFC] On the need of a `is_int_string` ? | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-124946@lists.php.net to get a copy of this message | ||
Hi,
When string is used as an array key, it's sometimes casted to an int.
As explained in https://www.php.net/manual/en/language.types.array.php:
"Strings containing valid decimal ints, unless the number is preceded by
a + sign, will be cast to the int type. E.g the key "8" will actually be
stored under 8. On the other 08 will not be cast as it isn't a valid
decimal integer."
This behavior cause some issues, especially for static analysis. As an
example https://phpstan.org/r/5a387113-de45-4bef-89af-b6c52adc5f69
vs real life https://3v4l.org/pDkoB
Currently most of static analysis rely on one/many native php functions to
describe types.
PHPStan/Psalm supports a
numeric-string thanks to the is_numeric method.
I don't think there is a native function to know if the key will be casted
to an int. The implementation would be something similar (but certainly
better and in C) to
```
function is_int_string(string $s): bool
{
if (!is_numeric($s)) {
return false;
}
$a[$s] = $s;
return array_keys($a) !== array_values($a);
}
```
Which gives:
is_numeric('08') => true
ctype_digit('08') => true
is_int_string('08') => false
is_numeric('8') => true
ctype_digit('8') => true
is_int_string('8') => true
is_numeric('+8') => true
ctype_digit('+8') => false
is_int_string('+8') => false
is_numeric('8.4') => true
ctype_digit('8.4') => false
is_int_string('8.4') => false
Such method would allow to easily introduce a int-string type in static
analysis and the opposite, a non-int-string one (cf
https://github.com/phpstan/phpstan/issues/10239#issuecomment-1837571316).
WDYT about adding a is_int_string method then ?
Thanks