Bug #72031 [Opn->Csd]: array_column() against an array of objects discards all values matching null

From: Date: Sat, 16 Apr 2016 07:59:49 +0000
Subject: Bug #72031 [Opn->Csd]: array_column() against an array of objects discards all values matching null
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-200583@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72031&edit=1 ID: 72031 Updated by: nikic@php.net Reported by: mark at lange dot demon dot co dot uk Summary: array_column() against an array of objects discards all values matching null -Status: Open +Status: Closed Type: Bug Package: Unknown/Other Function Operating System: All PHP Version: 7.0.6RC1 Block user comment: N Private report: N New Comment: Automatic comment on behalf of nikic Revision: http://git.php.net/?p=php-src.git;a=commit;h=c0d8dc5bd701aad68692f91334a46c1fa46a6d1e Log: Fixed bug #72031 Previous Comments: ------------------------------------------------------------------------ [2016-04-15 14:20:00] 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-15 14:17:17] 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:08:43] 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 13:46:49] 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" } ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72031&edit=1

« previous php.bugs (#200583) next »