php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72031 array_column() against an array of objects discards all values matching null
Submitted: 2016-04-15 13:46 UTC Modified: 2016-04-16 08:27 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: mark at lange dot demon dot co dot uk Assigned: nikic (profile)
Status: Closed Package: Unknown/Other Function
PHP Version: 7.0.6RC1 OS: All
Private report: No CVE-ID: None
 [2016-04-15 13:46 UTC] mark at lange dot demon dot co dot uk
Description:
------------
PHP7 extended array_column() to support reading a column of property values from an array of objects. However, if the property contains a value that loose-equates to null, that entry is not returned in the resulting array.

Applies to all PHP7 releases; http://lxr.php.net/xref/PHP_7_0/ext/standard/array.c#3569 appears to be the cause of the bug

The code test script demonstrates this problem.

Expected result is an array containing [-1,0,1,2,null,true,false,'abc','']

Actual result is an array containing [-1,1,2,true,'abc']

The 0, null, false and empty string values are all discarded

Test script:
---------------
class myObj {
    public $prop;
    public function __construct($prop) {
        $this->prop = $prop;
    }
}

$objects = [
    new myObj(-1),
    new myObj(0),
    new myObj(1),
    new myObj(2),
    new myObj(null),
    new myObj(true),
    new myObj(false),
    new myObj('abc'),
    new myObj(''),
];

var_dump(array_column($objects, 'prop'));


Expected result:
----------------
array(9) {
  [0]=>
  int(-1)
  [1]=>
  int(0)
  [2]=>
  int(1)
  [3]=>
  int(2)
  [4]=>
  null
  [5]=>
  bool(true)
  [6]=>
  bool(false)
  [7]=>
  string(3) "abc"
  [8]=>
  string(0) ""
}
[-1,0,1,2,null,true,false,'abc','']

Actual result:
--------------
array(5) {
  [0]=>
  int(-1)
  [1]=>
  int(1)
  [2]=>
  int(2)
  [3]=>
  bool(true)
  [4]=>
  string(3) "abc"
}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-15 14:08 UTC] nikic@php.net
The issue is http://lxr.php.net/xref/PHP_7_0/ext/standard/array.c#3526. It uses has_property in "set" mode, which corresponds to empty() semantics. What we want instead is "exists" mode. However, it looks like that mode currently ignores __isset completely, for some reason.

A partial fix would be to use "has" mode, so only NULL values are skipped (also wrong, but better than currently).
 [2016-04-15 14:17 UTC] mark at lange dot demon dot co dot uk
Unsure if it's related, but array_column() also ignores object properties that are numerics or invalid property names, even though these can exist (for example, when casting to a stdClass object from an array).

e.g

$objects = [
    (object)["3" => 1],
    (object)["3" => 2],
];

print_r($objects);
print_r(array_column($objects, 3));


and

$objects = [
    (object)["@invalidProperty" => 1],
    (object)["@invalidProperty" => 2],
];

print_r($objects);
print_r(array_column($objects, "@invalidProperty"));
 [2016-04-15 14:20 UTC] mark at lange dot demon dot co dot uk
If the above related to integer or invalid property names is unrelated, then I'll raise a separate bug report for it
 [2016-04-16 07:59 UTC] nikic@php.net
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c0d8dc5bd701aad68692f91334a46c1fa46a6d1e
Log: Fixed bug #72031
 [2016-04-16 07:59 UTC] nikic@php.net
-Status: Open +Status: Closed
 [2016-04-16 08:27 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 [2016-04-16 08:27 UTC] nikic@php.net
@mark: I can't reproduce the invalid property name issue, works fine for me. The numeric property name case is the usual issue of different type normalization for arrays and objects. It's a general issue with the object->array / array->object casts, not directly related to array_column.
 [2016-07-20 11:32 UTC] davey@php.net
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c0d8dc5bd701aad68692f91334a46c1fa46a6d1e
Log: Fixed bug #72031
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 10:01:28 2024 UTC