php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80309 numerical array keys converted to int in strict mode
Submitted: 2020-11-02 22:49 UTC Modified: 2020-11-03 09:43 UTC
From: shop1 at mokraemer dot de Assigned:
Status: Not a bug Package: Arrays related
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
 [2020-11-02 22:49 UTC] shop1 at mokraemer dot de
Description:
------------
numerical array keys are converted to integers.
In strict mode (typed properties, typed function parameters), this is not desireable.

Test script:
---------------
declare(strict_types=1);
function f(string $s):string{
	return $s;
}

$array=[
	'x'=>5,
	'1'=>6
];

foreach($array as $k => $v){
	echo f($k);
}


Expected result:
----------------
x1

Actual result:
--------------
xPHP Fatal error:  Uncaught TypeError: Argument 1 passed to f() must be of the type string, int given, called in /tmp/test.php on line 13 and defined in /tmp/test.php:3
Stack trace:
#0 /tmp/test.php(13): f()
#1 {main}
  thrown in /tmp/test.php on line 3


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-11-02 22:51 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2020-11-02 22:51 UTC] requinix@php.net
This is documented behavior for array keys and is not affected by strict_types.
 [2020-11-03 00:07 UTC] shop1 at mokraemer dot de
it is true, this is documented behaviour, but with strict types this becomes a problem. Since array keys do not keep the original type.
If this is kept, it means every array key must be explicitly converted back to string.
Using e.g. array_keys($array) to pass an array of strings does not work, you always have to reaply array_map('strval',array_keys($array))

This makes everything errorprone, it is hard to detect those errors, as users/databases,... may be the source of those values.
 [2020-11-03 00:39 UTC] requinix@php.net
You're right: by enabling strict_types you must now take responsibility for making sure that the types of your function arguments are correct.

Numeric strings as array keys causes multiple problems in other places and is not something that can be easily changed.
What can be easily changed is adding a "(string)" cast to your code.
 [2020-11-03 09:06 UTC] shop1 at mokraemer dot de
Thanks for your reply.
Maybe it is a good idea to advance strict_types to
declare(strict_types=2);
and that way no conversions are made and will get us to a more typesafe way.

It is hard to understand/handle putting strings in a "list" and getting a mixed type back. Using phan also suggests to declare it as e.g. array<string,string>, but if there is any user/db interaction all those declarations become weak and may fail at runtime.

Maybe this can be asked as a "feature request" to make even arrays more strict.
 [2020-11-03 09:43 UTC] requinix@php.net
That alone won't solve the problem...

If you feel strongly about this then check out the RFC process, which begins with someone bringing up the subject for discussion on the mailing list.
https://wiki.php.net/rfc/howto

Before you do that, please first research the matter of why array keys are not type-strict. There are important issues and common use cases to be aware of, such as with the $_GET/POST/etc. superglobals.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 17:01:30 2024 UTC