Recursive Array Diff Reporter
Compares nested arrays and reports added, removed, and changed paths.
Function signature
ogCompareNestedArrays(old_data, new_data, prefix = '')
Categories
- File and Upload Safety
Parameters
old_dataOriginal array.new_dataNew array.prefixInternal path prefix for recursive comparison.Return value
Short public-safe status message.
- added
- removed
- changed
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.
*/
/**
* Compares nested arrays and reports added, removed, and changed paths.
*
* Primary use case: Config audits, API response checks.
* Typical inputs: old array, new array.
* Typical output: change report array.
*
* Implementation note: Normalize scalar types before comparison if needed.
*
* @param array $old_data Original array.
* @param array $new_data New array.
* @param string $prefix Internal path prefix for recursive comparison.
* @return array Structured comparison report.
*/
function ogCompareNestedArrays($old_data, $new_data, $prefix = '') {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($old_data) || !is_array($new_data)) {
$result['message'] = 'Both comparison values must be arrays.';
return $result;
}
$added = array();
$removed = array();
$changed = array();
$keys = array_unique(array_merge(array_keys($old_data), array_keys($new_data)));
foreach ($keys as $key) {
$path = (string)$key;
if ($prefix !== '') {
$path = $prefix . '.' . $path;
}
$old_has_key = array_key_exists($key, $old_data);
$new_has_key = array_key_exists($key, $new_data);
if (!$old_has_key && $new_has_key) {
$added[$path] = $new_data[$key];
continue;
}
if ($old_has_key && !$new_has_key) {
$removed[$path] = $old_data[$key];
continue;
}
if (is_array($old_data[$key]) && is_array($new_data[$key])) {
$child = ogCompareNestedArrays($old_data[$key], $new_data[$key], $path);
if (!empty($child['data']['added'])) {
$added = array_merge($added, $child['data']['added']);
}
if (!empty($child['data']['removed'])) {
$removed = array_merge($removed, $child['data']['removed']);
}
if (!empty($child['data']['changed'])) {
$changed = array_merge($changed, $child['data']['changed']);
}
continue;
}
if ($old_data[$key] !== $new_data[$key]) {
$changed[$path] = array(
'old' => $old_data[$key],
'new' => $new_data[$key]
);
}
}
$result['success'] = true;
$result['message'] = 'Nested arrays compared.';
$result['data'] = array(
'added' => $added,
'removed' => $removed,
'changed' => $changed,
'change_count' => count($added) + count($removed) + count($changed)
);
return $result;
}