Nested Array Diff Report
Creates a dot-path diff report for changed, added, and removed values inside nested arrays.
Purpose
Creates a dot-path diff report for changed, added, and removed values inside nested arrays.
Snippet details
ContextArrayLevelAdvancedCopy-and-paste statusMarked safe after review.Categories
- Security
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.
*/
/**
* Nested Array Diff Report.
*
* Purpose:
* Compares two nested arrays and reports added, removed, and changed values
* using dot-path keys that are easy to display in an audit screen.
*
* @param array $before Previous nested array state.
* @param array $after New nested array state.
* @param string $prefix Internal dot-path prefix.
* @return array Nested array diff report.
*/
function ogSnippetNestedArrayDiffReport(array $before, array $after, string $prefix = ''): array {
$changes = array();
$keys = array();
foreach ($before as $key => $value) {
$keys[$key] = $key;
}
foreach ($after as $key => $value) {
$keys[$key] = $key;
}
foreach ($keys as $key) {
$path = (string) $key;
if ($prefix !== '') {
$path = $prefix.'.'.$path;
}
$before_exists = array_key_exists($key, $before);
$after_exists = array_key_exists($key, $after);
if ($before_exists === false) {
$changes[] = array('path' => $path, 'type' => 'added', 'before' => null, 'after' => $after[$key]);
continue;
}
if ($after_exists === false) {
$changes[] = array('path' => $path, 'type' => 'removed', 'before' => $before[$key], 'after' => null);
continue;
}
if (is_array($before[$key]) === true && is_array($after[$key]) === true) {
$nested_changes = ogSnippetNestedArrayDiffReport($before[$key], $after[$key], $path);
foreach ($nested_changes as $nested_change) {
$changes[] = $nested_change;
}
continue;
}
if ($before[$key] !== $after[$key]) {
$changes[] = array('path' => $path, 'type' => 'changed', 'before' => $before[$key], 'after' => $after[$key]);
}
}
return $changes;
}
$before = array('ship' => array('name' => 'Rocinante', 'status' => 'docked'));
$after = array('ship' => array('name' => 'Rocinante', 'status' => 'burning'));
$diff_report = ogSnippetNestedArrayDiffReport($before, $after);
echo 'The Expanse nested array diff count: '.count($diff_report);