Hi all,
Adding these two array functions has been on the TODO for a while, and my
original patch has been collecting dust for almost 2 years. :-) I just
updated the patches now after some small changes (the original version for
5.2 is currently linked on the wiki). A brief description, if I remember
correctly, especially the recursive version (Lukas can maybe give more info.
since he created the original implementation in PHP ;-)):
array_replace()
is like the + operator applied to arrays, except that it
WILL overwrite ("replace") existing entries. array_replace_recursive()
will
do the same except that it becomes recursive only when both the destination
and source entries are arrays, otherwise the new source entry still replaces
any existing one.
In the wrapper function, I removed the SEPARATE_ZVAL() and
convert_to_array_ex() as they appear to be leftover from PHP 4 (before
array_merge[_recursive] checked if the args were arrays first). This made a
big performance difference when I benchmarked 2 years ago! I also updated
it to use array_init_size() (returned array will have at least as many
elements as the largest input array) for another small optimization.
http://realplain.com/php/array_replace.diff
http://realplain.com/php/array_replace_5_3.diff (With NEWS entry)
http://realplain.com/php/array_replace.phpt (Still has the old UEXPECT
section for HEAD; will fix if I commit)
Any thoughts or objections? Should I commit before Thursday, like
tomorrow...?
Thanks,
Matt
Matt Wilmas wrote:
array_replace()
is like the + operator applied to arrays, except that it
WILL overwrite ("replace") existing entries.
Excuse my ignorance but what's the difference between
$array = array_replace($array1, $array2);
and
$array = $array2 + $array1;
apart from different order of the entries in the resulting array?
array_replace_recursive()
will do the same except that it becomes
recursive only when both the destination and source entries are
arrays, otherwise the new source entry still replaces any existing
one.
Hmm, generic enough to be included?
- Chris
array_replace_recursive()
will do the same except that it becomes
recursive only when both the destination and source entries are
arrays, otherwise the new source entry still replaces any existing
one.Hmm, generic enough to be included?
A frequent use case is merging a multi dimensional configuration array
with a multi dimensional array containing defaults. At the same time I
cannot find a single use case for the current array_merge_recursive()
.
regards,
Lukas Kahwe Smith
mls@pooteeweet.org
Hi Christian,
----- Original Message -----
From: "Christian Schneider"
Sent: Wednesday, July 23, 2008
Matt Wilmas wrote:
array_replace()
is like the + operator applied to arrays, except that it
WILL overwrite ("replace") existing entries.Excuse my ignorance but what's the difference between
$array = array_replace($array1, $array2);
and
$array = $array2 + $array1;
apart from different order of the entries in the resulting array?
The order of the entries is the only difference, I believe. :-) I think
that's desirable however, and having the non-recursive version makes it
match array_merge()
, etc. As for bloat or something, there's virtually no
extra code: only PHP_FUNCTION() and then in the wrapper function it just
uses zend_hash_merge() just like the + operator, except with its "overwrite"
param set to 1.
array_replace_recursive()
will do the same except that it becomes
recursive only when both the destination and source entries are
arrays, otherwise the new source entry still replaces any existing
one.Hmm, generic enough to be included?
What Lukas said. :-)
- Chris
- Matt
Matt,
Adding these two array functions has been on the TODO for a while,
The patch can quite easily be tricked into an endless recursion of
php_array_replace_recursive() calls which will segfault:
$ php -r '$a = array(); $a[] = &$a; $b = array(); $b[] = &$b;
array_replace_recursive($a, $b);'
Segmentation fault
Some other cases were covered by PHP's recursion detection:
$ php -r '$a = array(); $a[1] = &$a; $b = array(); $b[2] = &$b;
array_replace_recursive($a, $b, array(&$a, &$b), array(&$b, &$a));'
Warning: array_replace_recursive()
: recursion detected in Command line
code on line 1
Can you try to add a detection for the first case?
johannes