php
52 lines · 8 steps
Layered config merging in PHP
A resolver folds any number of override layers onto defaults with a recursive deep merge and list deduplication.
Explained by
highlit
1final class ConfigResolver
2{
3 private array $merged;
4
5 public function __construct(array $defaults, array ...$overrides)
6 {
7 $this->merged = array_reduce(
8 $overrides,
9 fn (array $carry, array $layer): array => $this->deepMerge($carry, $layer),
10 $defaults
11 );
12 }
13
14 public function all(): array
15 {
16 return $this->merged;
17 }
18
19 private function deepMerge(array $base, array $layer): array
20 {
21 foreach ($layer as $key => $value) {
22 if (is_int($key)) {
23 $base[] = $value;
24 continue;
25 }
26
27 if (is_array($value) && isset($base[$key]) && is_array($base[$key])) {
28 $base[$key] = $this->deepMerge($base[$key], $value);
29 continue;
30 }
31
32 $base[$key] = $value;
33 }
34
35 return $this->dedupeLists($base);
36 }
37
38 private function dedupeLists(array $config): array
39 {
40 foreach ($config as $key => $value) {
41 if (!is_array($value)) {
42 continue;
43 }
44
45 $config[$key] = array_is_list($value)
46 ? array_values(array_unique($value, SORT_REGULAR))
47 : $this->dedupeLists($value);
48 }
49
50 return $config;
51 }
52}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Folding layers with array_reduce turns any number of overrides into one clean accumulation.
- 2Distinguishing integer keys from string keys lets one merge routine handle both lists and maps.
- 3Recursing into nested arrays keeps deep structures merged rather than blindly overwritten.
Related explainers
php
<?php function buildTree(array $items, ?int $parentId = null): array {
Building a tree from a flat list in PHP
recursion
tree
grouping
Intermediate
6 steps
php
<?php function uploadDocument(string $endpoint, string $filePath, array $meta): array {
Uploading a file with cURL in PHP
curl
file-upload
http
Intermediate
8 steps
php
<?php namespace App\Console\Commands;
Streaming CSV imports in Laravel
lazy-evaluation
generators
batch-processing
Intermediate
7 steps
php
<?php namespace App\Services;
Resilient HTTP retries with Laravel's client
http-client
retry-logic
error-handling
Intermediate
7 steps
php
<?php namespace App\Services;
Building signed, expiring download URLs in PHP in Laravel
hmac
url-signing
authentication
Intermediate
7 steps
php
<?php declare(strict_types=1);
A single-action JSON user controller in PHP
invokable-class
json-api
validation
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/layered-config-merging-in-php-explained-php-81f1/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.