Skip to content
← Back to Functions
Code

Config Overlay Merger

Merges default, environment, and local config arrays with controlled override rules.

Function signature

ogMergeConfigOverlay(base_config = array(), overlays = array(), options = array())

Categories

  • System Health

Parameters

base_configDefault configuration.overlaysOrdered overlay arrays.optionsOptional strict mode and protected keys. Recognized keys: `protected_keys`, `strict`.

Return value

Short public-safe status message.

  • config
  • rejected_keys
  • rejected_count

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Merges default, environment, and local config arrays with controlled override rules.
 *
 * Primary use case: Site configuration and feature flags.
 * Typical inputs: base config, override arrays.
 * Typical output: merged config.
 *
 * Implementation note: Reject unknown keys when strict mode is enabled.
 *
 * @param array $base_config Default configuration.
 * @param array $overlays Ordered overlay arrays.
 * @param array $options Optional strict mode and protected keys.
 * @return array Structured merged configuration result.
 */
function ogMergeConfigOverlay($base_config = array(), $overlays = array(), $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	if (!is_array($base_config)) {
		$result['message'] = 'Base config must be an array.';
		return $result;
	}
	if (!is_array($overlays)) {
		$result['message'] = 'Overlays must be an array.';
		return $result;
	}
	if (!is_array($options)) {
		$options = array();
	}

	$strict = false;
	if (!empty($options['strict'])) {
		$strict = true;
	}
	$protected_keys = array();
	if (!empty($options['protected_keys']) && is_array($options['protected_keys'])) {
		$protected_keys = $options['protected_keys'];
	}

	$merged = $base_config;
	$rejected = array();
	foreach ($overlays as $overlay_name => $overlay) {
		if (!is_array($overlay)) {
			continue;
		}
		foreach ($overlay as $key => $value) {
			$key = (string)$key;
			if (in_array($key, $protected_keys, true)) {
				$rejected[] = $overlay_name . ':' . $key;
				continue;
			}
			if ($strict && !array_key_exists($key, $base_config)) {
				$rejected[] = $overlay_name . ':' . $key;
				continue;
			}
			$merged[$key] = $value;
		}
	}

	$result['success'] = true;
	$result['message'] = 'Config overlays merged.';
	$result['data'] = array(
		'config' => $merged,
		'rejected_keys' => $rejected,
		'rejected_count' => count($rejected)
	);

	return $result;
}