These three functions call themselves recursively and handle any nesting levels of arrays/objects/values and do strict comparisons. The entry-point to this function set would be "valuesAreIdentical".
<?php
function valuesAreIdentical($v1, $v2): bool {
$type1 = gettype($v1);
$type2 = gettype($v2);
if($type1 !== $type2){
return false;
}
switch(true){
case ($type1==='boolean' || $type1==='integer' || $type1==='double' || $type1==='string'):
if($v1 !== $v2){
return false;
}
break;
case ($type1==='array'):
$bool = arraysAreIdentical($v1, $v2);
if($bool===false){
return false;
}
break;
case 'object':
$bool = objectsAreIdentical($v1,$v2);
if($bool===false){
return false;
}
break;
case 'NULL':
break;
case 'resource':
break;
case 'unknown type':
break;
} return true;
}
function objectsAreIdentical($o1, $o2): bool {
if($o1 != $o2){
return false;
}
$objReflection1 = new ReflectionObject($o1);
$objReflection2 = new ReflectionObject($o2);
$arrProperties1 = $objReflection1->getProperties(ReflectionProperty::IS_PUBLIC);
$arrProperties2 = $objReflection2->getProperties(ReflectionProperty::IS_PUBLIC);
$bool = arraysAreIdentical($arrProperties1, $arrProperties2);
if($bool===false){
return false;
}
foreach($arrProperties1 as $key=>$propName){
$bool = valuesAreIdentical($o1->$propName, $o2->$propName);
if($bool===false){
return false;
}
}
return true;
}
function arraysAreIdentical(array $arr1, array $arr2): bool {
$count = count($arr1);
if(count($arr2) !== $count){
return false;
}
$arrKeysInCommon = array_intersect_key($arr1, $arr2);
if(count($arrKeysInCommon)!== $count){
return false;
}
$arrKeys1 = array_keys($arr1);
$arrKeys2 = array_keys($arr2);
foreach($arrKeys1 as $key=>$val){
if($arrKeys1[$key] !== $arrKeys2[$key]){
return false;
}
}
foreach($arr1 as $key=>$val){
$bool = valuesAreIdentical($arr1[$key], $arr2[$key]);
if($bool===false){
return false;
}
}
return true;
}
?>