php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #34834 array_merge_recursive() merges arrays with objects with arrays
Submitted: 2005-10-11 23:35 UTC Modified: 2021-09-14 15:06 UTC
Votes:10
Avg. Score:3.5 ± 1.7
Reproduced:5 of 6 (83.3%)
Same Version:1 (20.0%)
Same OS:4 (80.0%)
From: tomas_matousek at hotmail dot com Assigned:
Status: Verified Package: Arrays related
PHP Version: 5CVS-2005-11-02 (cvs) OS: *
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: tomas_matousek at hotmail dot com
New email:
PHP Version: OS:

 

 [2005-10-11 23:35 UTC] 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)
    }
  }
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-11-04 09:49 UTC] 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.
 [2016-12-30 23:10 UTC] cmb@php.net
-Package: Feature/Change Request +Package: Arrays related
 [2021-09-14 15:06 UTC] cmb@php.net
-Type: Feature/Change Request +Type: Documentation Problem
 [2021-09-14 15:06 UTC] cmb@php.net
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>
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 09 19:01:27 2024 UTC