<?php
interface ModifierInterface
{
public function apply(array $data, string $key): array;
}
class ArrayHelper
{
public static function mergeReverse(...$args): array
{
return self::applyModifiers(self::performMergeReverse(...$args));
}
public static function merge(...$args): array
{
return self::applyModifiers(self::performMerge(...$args));
}
private static function performMergeReverse(...$args): array
{
$res = array_pop($args) ?: [];
while (!empty($args)) {
foreach (array_pop($args) as $k => $v) {
if (is_int($k)) {
if (array_key_exists($k, $res) && $res[$k] !== $v) {
$res[] = $v;
} else {
$res[$k] = $v;
}
} elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
$res[$k] = self::performMergeReverse($v, $res[$k]);
} elseif (!isset($res[$k])) {
$res[$k] = $v;
}
}
}
return $res;
}
private static function performMerge(...$args): array
{
$res = array_shift($args) ?: [];
while (!empty($args)) {
foreach (array_shift($args) as $k => $v) {
if (is_int($k)) {
if (array_key_exists($k, $res) && $res[$k] !== $v) {
$res[] = $v;
} else {
$res[$k] = $v;
}
} elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
$res[$k] = self::performMerge($res[$k], $v);
} else {
$res[$k] = $v;
}
}
}
return $res;
}
public static function applyModifiers(array $data): array
{
$modifiers = [];
foreach ($data as $k => $v) {
if ($v instanceof ModifierInterface) {
$modifiers[$k] = $v;
unset($data[$k]);
} elseif (is_array($v)) {
$data[$k] = self::applyModifiers($v);
}
}
foreach ($modifiers as $key => $modifier) {
$data = $modifier->apply($data, $key);
}
return $data;
}
}
$package = [
'ApplicationStartup::class' => [
['WebAppInfoCollector::class', 'collect'],
],
'ApplicationShutdown::class' => [
['WebAppInfoCollector::class', 'collect'],
],
];
$app = [
'ApplicationStartup::class' => [
['AppStartup::class', 'start'],
],
'ApplicationShutdown::class' => [
['AppShutdown::class', 'shutdown'],
],
];
$result = ArrayHelper::merge($package, $app);
var_export($result);
echo "\n\n";
$resultPop = ArrayHelper::mergeReverse($package, $app);
var_export($resultPop);
- Output for 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.33, 8.2.0 - 8.2.29, 8.3.0 - 8.3.25, 8.4.1 - 8.4.12
- array (
'ApplicationStartup::class' =>
array (
0 =>
array (
0 => 'WebAppInfoCollector::class',
1 => 'collect',
),
1 =>
array (
0 => 'AppStartup::class',
1 => 'start',
),
),
'ApplicationShutdown::class' =>
array (
0 =>
array (
0 => 'WebAppInfoCollector::class',
1 => 'collect',
),
1 =>
array (
0 => 'AppShutdown::class',
1 => 'shutdown',
),
),
)
array (
'ApplicationStartup::class' =>
array (
0 =>
array (
0 => 'AppStartup::class',
1 => 'start',
),
1 =>
array (
0 => 'WebAppInfoCollector::class',
1 => 'collect',
),
),
'ApplicationShutdown::class' =>
array (
0 =>
array (
0 => 'AppShutdown::class',
1 => 'shutdown',
),
1 =>
array (
0 => 'WebAppInfoCollector::class',
1 => 'collect',
),
),
)
preferences:
74.69 ms | 410 KiB | 5 Q