Req->Doc #34834 [Ver]: array_merge_recursive() merges arrays with objects with arrays

[email protected]
Newsgroups php.doc.bugs
Message-ID <[email protected]>
Edit report at https://bugs.php.net/bug.php?id=34834&edit=1

 ID:                 34834
 Updated by:         [email protected]
 Reported by:        tomas_matousek at hotmail dot com
 Summary:            array_merge_recursive() merges arrays with objects
                     with arrays
 Status:             Verified
-Type:               Feature/Change Request
+Type:               Documentation Problem
 Package:            Arrays related
 Operating System:   *
 PHP Version:        5CVS-2005-11-02 (cvs)
 Block user comment: N
 Private report:     N

 New Comment:

I have to admit that this behavior[1] is unintuitive, and might
not have been the best design decision.  However, changing it
after so many years is likely to break code which relies on it. As
such, this should go through the RFC process[2].  Anybody is
welcome to pursue it.

Anyhow, more important than to change the behavior, is to properly
document it.  There is no indication on the man page[3], so I'm
changing this ticket to documentation problem.

[1] <https://3v4l.org/vmrnK>
[2] <https://wiki.php.net/rfc/howto>
[3] <https://www.php.net/array_merge_recursive>


Previous Comments:
------------------------------------------------------------------------
[2015-11-04 09:49:52] saboteur at saboteur dot me

You get even more interesting result using datetime.

Code:
-------
<?php

$old = ['created' => new \DateTime()];
$new = ['created' => new \DateTime('+1 minute')];

$changeset = array_merge_recursive($old, $new);

var_dump($changeset);

Expected:
---------
array(1) {
  ["created"]=>
  array(2) {
    [0] => object(DateTime)#1 (3) {
      ["date"]=>
        string(26) "2015-11-04 10:36:03.000000"
      ["timezone_type"]=>
        int(3)
      ["timezone"]=>
        string(16) "Europe/Amsterdam"
    },
    [1] => object(DateTime)#1 (3) {
      ["date"]=>
        string(26) "2015-11-04 10:37:03.000000"
      ["timezone_type"]=>
        int(3)
      ["timezone"]=>
        string(16) "Europe/Amsterdam"
    }
  }
}

Actual
-------
array(1) {
  ["created"]=>
  array(3) {
    ["date"]=>
    array(2) {
      [0]=>
      string(26) "2015-11-04 10:36:03.000000"
      [1]=>
      string(26) "2015-11-04 10:37:03.000000"
    }
    ["timezone_type"]=>
    array(2) {
      [0]=>
      int(3)
      [1]=>
      int(3)
    }
    ["timezone"]=>
    array(2) {
      [0]=>
      string(16) "Europe/Amsterdam"
      [1]=>
      string(16) "Europe/Amsterdam"
    }
  }
}

So that treats DateTime as array.

------------------------------------------------------------------------
[2005-10-11 23:35:21] tomas_matousek at hotmail dot com

Description:
------------
Although one cannot pass obejects to array_merge_recursive() function, it looks like it doesn't ignore objects at all.
If objects are contained in the array it merges them as if they were arrays of fields. I think it is not good to treat objects in this way when other array functions doesn't do so (e.g. array_walk_recursive doesn't step to fields of objects).

Reproduce code:
---------------
class A 
{ 
  var $field = array(1);
}

$a = new A;
$x = array("a" => $a);

$y = array("a" => array("field" => array(2)));

var_dump(array_merge_recursive($x,$y));

Expected result:
----------------
array(1) {
  ["a"]=>
  array(2) {
    [0]=>
    object(A)#1 (1) {
      ["field"]=>
      array(1) {
        [0]=>
        int(1)
      }
    }
    ["field"]=>
    array(1) {
      [0]=>
      int(2)
    }
  }
}


Actual result:
--------------
array(1) {
  ["a"]=>
  array(1) {
    ["field"]=>
    array(2) {
      [0]=>
      int(1)
      [1]=>
      int(2)
    }
  }
}



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=34834&edit=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.