]> granicus.if.org Git - php/commitdiff
Fixed bug #72031
authorNikita Popov <nikic@php.net>
Fri, 15 Apr 2016 14:28:48 +0000 (16:28 +0200)
committerNikita Popov <nikic@php.net>
Sat, 16 Apr 2016 07:58:57 +0000 (09:58 +0200)
NEWS
ext/standard/array.c
ext/standard/tests/array/bug72031.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 493c6361d31c8bd00abddd41be5722c283974ae1..ad8d4a5e5d1308834ed4be854f43d9118713f705 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,10 @@ PHP                                                                        NEWS
 - SQLite3:
   . Fixed bug #68849 (bindValue is not using the right data type). (Anatol)
 
+- Standard:
+  . Fixed bug #72031 (array_column() against an array of objects discards all
+    values matching null). (Nikita)
+
 28 Apr 2016 PHP 7.0.6
 
 - Core:
index a0cdd91d855b8d7ad226d6e1bed2dbc22f786e4e..6f01198aef63b84d223b3dae7a181ce66abc4a7a 100644 (file)
@@ -3523,9 +3523,15 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv)
        if (Z_TYPE_P(data) == IS_OBJECT) {
                zend_string *key = zval_get_string(name);
 
-               if (!Z_OBJ_HANDLER_P(data, has_property) || Z_OBJ_HANDLER_P(data, has_property)(data, name, 1, NULL)) {
+               /* The has_property check is first performed in "exists" mode (which returns true for
+                * properties that are null but exist) and then in "has" mode to handle objects that
+                * implement __isset (which is not called in "exists" mode). */
+               if (!Z_OBJ_HANDLER_P(data, has_property)
+                               || Z_OBJ_HANDLER_P(data, has_property)(data, name, 2, NULL)
+                               || Z_OBJ_HANDLER_P(data, has_property)(data, name, 0, NULL)) {
                        prop = zend_read_property(Z_OBJCE_P(data), data, ZSTR_VAL(key), ZSTR_LEN(key), 1, rv);
                }
+
                zend_string_release(key);
        } else if (Z_TYPE_P(data) == IS_ARRAY) {
                if (Z_TYPE_P(name) == IS_STRING) {
diff --git a/ext/standard/tests/array/bug72031.phpt b/ext/standard/tests/array/bug72031.phpt
new file mode 100644 (file)
index 0000000..541fd3c
--- /dev/null
@@ -0,0 +1,48 @@
+--TEST--
+Bug #72031: array_column() against an array of objects discards all values matching null
+--FILE--
+<?php
+
+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'));
+
+?>
+--EXPECT--
+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) ""
+}