src/Traits/Collections.php
public static function concatDeep($collection1, $collection2)
    {
        return __::reduceRight(func_get_args(), function ($source, $result) {
            __::doForEach($source, function ($sourceValue, $key) use (&$result) {
                if (!__::has($result, $key)) {
                    $result = __::set($result, $key, $sourceValue);
                } else {
                    if (is_numeric($key)) {
                        $result = __::concat($result, [$sourceValue]);
                    } else {
                        $resultValue = __::get($result, $key);
                        $result = __::set($result, $key, __::concatDeep(
                            __::isCollection($resultValue) ? $resultValue : (array)$resultValue,
                            __::isCollection($sourceValue) ? $sourceValue : (array)$sourceValue
                        ));
                    }
                }
            });

            return $result;
        }, []);
    }
public static function concatDeep($collection1, $collection2)
    {
        return __::reduceRight(func_get_args(), function ($source, $result) {
            __::doForEach($source, function ($sourceValue, $key) use (&$result) {
                if (!__::has($result, $key)) {
                    $result = __::set($result, $key, $sourceValue);
                } else {
                    if (is_numeric($key)) {
                        $result = __::concat($result, [$sourceValue]);
                    } else {
                        $resultValue = __::get($result, $key);
                        $result = __::set($result, $key, __::concatDeep(
                            __::isCollection($resultValue) ? $resultValue : (array)$resultValue,
                            __::isCollection($sourceValue) ? $sourceValue : (array)$sourceValue
                        ));
                    }
                }
            });

            return $result;
        }, []);
    }
public static function concatDeep ( $ collection1 , $ collection2 ) { return __ :: reduceRight ( func_get_args ( ) , function ( $ source , $ result ) { __ :: doForEach ( $ source , function ( $ sourceValue , $ key ) use ( & $ result ) { if ( ! __ :: has ( $ result , $ key ) ) { $ result = __ :: set ( $ result , $ key , $ sourceValue ) ; } else { if ( is_numeric ( $ key ) ) { $ result = __ :: concat ( $ result , [ $ sourceValue ] ) ; } else { $ resultValue = __ :: get ( $ result , $ key ) ; $ result = __ :: set ( $ result , $ key , __ :: concatDeep ( __ :: isCollection ( $ resultValue ) ? $ resultValue : ( array ) $ resultValue , __ :: isCollection ( $ sourceValue ) ? $ sourceValue : ( array ) $ sourceValue ) ) ; } } } ) ; return $ result ; } , [ ] ) ; }
Recursively combines and concat collections provided with each others.

If the collections have common keys, then the values are appended in an array.
If numerical indexes are passed, then values are appended.

For a non-recursive concat, see __::concat.

@usage __::concatDeep(['color' => ['favorite' => 'red', 5], 3], [10, 'color' => ['favorite' => 'green',
'blue']]);
>> ['color' => ['favorite' => ['red', 'green'], 5, 'blue'], 3, 10]

@param array|object $collection1 First collection to concatDeep.
@param array|object $collection2 other collections to concatDeep.

@return array|object Concatenated collection.
Recursively combines and concat collections provided with each others .