On Wed, Dec 29, 2021 at 4:42 PM Vincent Langlet <[email protected]>
wrote:

> Hi,
>
> I recently discovered that an array was automatically casting
> numeric-string keys to int if it was possible. For instance, the following
> array:
>
> $a = ['01' => '01', '10' => '10'];
>
> Is not an array with the key '01' and '10' but instead consider the second
> key as an int.
>
> This has some implications like the fact that
> - array_flip(array_flip($a)) !== $a
> - array_search('10', $a) is an int when array_search('01', $a) is still a
> string. Someone using strict types and passing the result to a function
> expecting a string could end with an unexpected crash.
>
> I've created an issue about this
> https://github.com/php/php-src/issues/7845
> but it was recommended to me to send a mail to this mailing list instead.
>
> I don't think this behavior should be considered as "normal" and would like
> to propose to change this for PHP 9, as it's a BC-break. To me it can and
> be considered as a follow-up of
> https://wiki.php.net/rfc/string_to_number_comparison and
> ttps://wiki.php.net/rfc/saner-numeric-strings
> <https://wiki.php.net/rfc/saner-numeric-strings>. This is still a
> "concept"
> since I never code with C and know nothing about the PHP implementation and
> if this change would be possible. Any help is welcome then.
>
> Thanks
>

Hi,

While I'd love for this inconsistency to go away, I also know that this is
most likely such a big change that it causes months of work and broken code
because it relies on this behavior. It wouldn't surprise me if this
singular change would cause more work than all previous BC breaks combined.
This behavior is documented: PHP: Arrays - Manual
<https://www.php.net/manual/en/language.types.array.php>

The key can either be an int or a string. The value can be of any type.
>
> Additionally the following key casts will occur:
>
>    - 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 hand "08" will not be cast, as it isn't a
>    valid decimal integer.
>    - Floats are also cast to ints, which means that the fractional part
>    will be truncated. E.g. the key 8.7 will actually be stored under 8.
>    - Bools are cast to ints, too, i.e. the key true will actually be
>    stored under 1 and the key false under 0.
>    - Null will be cast to the empty string, i.e. the key null will
>    actually be stored under "".
>    - Arrays and objects can not be used as keys. Doing so will result in
>    a warning: Illegal offset type.
>
>

Reply via email to