Bug #76587 [Com]: array_column gives incorrect result if $indexKey selects a float
| From: | danack@php.net | Date: | Fri, 06 Jul 2018 13:57:24 +0000 |
| Subject: | Bug #76587 [Com]: array_column gives incorrect result if $indexKey selects a float | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-216172@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=76587&edit=1
ID: 76587
Comment by: danack@php.net
Reported by: rowan dot collins at gmail dot com
Summary: array_column gives incorrect result if $indexKey
selects a float
Status: Analyzed
Type: Bug
Package: Arrays related
PHP Version: 7.2.7
Block user comment: N
Private report: N
New Comment:
The issue seems to be the code in array_column appears to not cater for floats at all and to instead
use add_next_index_zval to add the next value, if the key was going to be a float.
if (Z_TYPE_P(zkeyval) == IS_STRING) {
zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(zkeyval), zcolval);
} else if (Z_TYPE_P(zkeyval) == IS_LONG) {
add_index_zval(return_value, Z_LVAL_P(zkeyval), zcolval);
} else if (Z_TYPE_P(zkeyval) == IS_OBJECT) {
zend_string *tmp_key;
zend_string *key = zval_get_tmp_string(zkeyval, &tmp_key);
zend_symtable_update(Z_ARRVAL_P(return_value), key, zcolval);
zend_tmp_string_release(tmp_key);
} else {
add_next_index_zval(return_value, zcolval);
}
Possibly related:
https://bugs.php.net/bug.php?id=68553
Just to note, even if array_column worked as it possibly should - for your case it still won't
give you the expected output as floats get cast to ints for array keys:
```
$foo = [
2.5 => 'whatever'
];
var_dump($foo);
//output is:
array(1) {
[2] =>
string(8) "whatever"
}
```
As such - it's possible to see why that behaviour was chosen. Using add_next_index_zval avoids
overwriting columns in some cases......but, ewwww - not all:
```
$a = [
[ 'foo' => 0.5 ],
[ 'foo' => 0 ],
[ 'foo' => '0' ],
];
var_dump(array_column($a, 'foo', 'foo'));
// output is
array(1) {
[0]=>
string(1) "0"
}
```
Previous Comments:
------------------------------------------------------------------------
[2018-07-06 13:56:31] cmb@php.net
I can confirm the described behavior: <https://3v4l.org/Yvaup>.
However, I'm not sure that qualifies as bug, since the docs[1]
state:
| This value may be the integer key of the column, or it may be
| the string key name.
Anyhow, if we would change the current behavior (BC break!), we 'd
had to adapt this code[2] (cast FLOAT to INT), or perhaps even
treat the $column_key parameter in the same way and adapt
array_column_fetch_prop()[3].
[1] <http://php.net/manual/en/function.array-column.php>
[2] <https://github.com/php/php-src/blob/af341213f73650b28b74b374501d84060eb604ab/ext/standard/array.c#L4177-L4182>
[3] <https://github.com/php/php-src/blob/af341213f73650b28b74b374501d84060eb604ab/ext/standard/array.c#L4111-L4115>
------------------------------------------------------------------------
[2018-07-06 13:14:42] rowan dot collins at gmail dot com
Description:
------------
When array_column is used with the $indexKey parameter, and the selected index is a float, it is
ignored, and treated as an array-append operation.
This is unexpected, because attempting to use a float as a key would normally result in it being
cast to either an integer or a string.
Note that this is similar to Bug #68553, where null keys are also treated as array-appends.
As with that bug, the polyfill implemented in userland behaves as expected. HHVM's
implementation seems to cast all floats to integer, so float(2.5) becomes int(2) rather than
string("2.5").
Test script:
---------------
$a = [
[ 'foo' => 1.0 ],
[ 'foo' => 2.5 ],
[ 'foo' => 3 ],
[ 'foo' => '4' ],
];
var_dump(array_column($a, 'foo', 'foo'));
Expected result:
----------------
array(4) {
[1] => float(1)
["2.5"] => float(2.5)
[3] => int(3)
[4] => string(1) "4"
}
Actual result:
--------------
array(4) {
[0] => float(1)
[1] => float(2.5)
[3] => int(3)
[4] => string(1) "4"
}
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=76587&edit=1