Делаем умный объект из многомерного массива

С объектами работать удобнее из за их синтаксиса и потому что в них можно обрабатывать несуществующие свойства, если они запрашиваются при этом не получая никаких PHP нотисов.

Функция ниже превращает переданный массив в объект. Массив можно передать любого уровня вложенности, тогда все вложенные.

/**
 * Recursively converts all array data to an objects.
 *
 * @php 8.2
 * @author Kama (wp-kama.ru)
 * @version 3.4
 *
 * @param array $data
 *
 * @return object|mixed
 */
function array_to_object( $data ){

	if(
		! is_array( $data )
		|| empty( $data )
		|| array_keys( $data ) === range( 0, count( $data ) - 1 ) // is_indexed_array
	)
		return $data;

	foreach( $data as & $val ){
		$val = (__FUNCTION__)( maybe_unserialize( $val ) );
	}
	unset( $val );

	return new Array_To_Object_Helper( $data );
}

#[\AllowDynamicProperties]
final class Array_To_Object_Helper implements ArrayAccess {

	public function __construct( $data ){

		foreach( $data as $key => $val ){
			$this->$key = $val;
		}
	}

	/** @noinspection MagicMethodsValidityInspection */
	public function __get( $name ){
		return $this->$name ?? null;
	}

	#[\ReturnTypeWillChange]
	public function offsetGet( $name ){
		return $this->$name ?? null;
	}

	#[\ReturnTypeWillChange]
	public function offsetExists( $name ){
		return isset( $this->$name );
	}

	#[\ReturnTypeWillChange]
	public function offsetSet( $name, $val ){
		$this->$name = $val;
	}

	#[\ReturnTypeWillChange]
	public function offsetUnset( $name ){
		unset( $this->$name );
	}

}

Пример использования:

$arr = [
	'aaa',
	'foo' => 'bar',
	'null' => null,
	'null' => 123,
	'empty_arr' => [],
	'arr2' => [ 1, 2, 3 ],
	'arr3' => [
		'somekey' => 123
	],
	'4arr' => [
		'key' => [
			'фыв' => ['1234'=>'1234']
		]
	],
];

$obj = array_to_object( $arr );

print_r( $obj );

Результат:

class@anonymous Object
(
	[0] => aaa
	[foo] => bar
	[null] => 123
	[empty_arr] => Array
		(
		)

	[arr2] => Array
		(
			[0] => 1
			[1] => 2
			[2] => 3
		)

	[arr3] => class@anonymous Object
		(
			[somekey] => 123
		)

	[4arr] => class@anonymous Object
		(
			[key] => class@anonymous Object
				(
					[фыв] => class@anonymous Object
						(
							[1234] => 1234
						)
				)
		)
)

Получаем отдельные данные из объекта (обратите внимание что значения можно получать как элементы массива или объекта):

print_r( $obj->arr2 );
print_r( $obj['arr2'] );
/*
Array
(
	[0] => 1
	[1] => 2
	[2] => 3
)
*/

var_dump( $obj->arr3->somekey );     // int(123)
var_dump( $obj->arr3['somekey'] );   // int(123)
var_dump( $obj['arr3']['somekey'] ); // int(123)

var_dump( $obj->not_exists );   // NULL
var_dump( $obj['not_exists'] ); // NULL

Пример добавления данных в объект:

$obj['nono'] = 123;
var_dump( $obj['nono'] ); // int(123)

$obj->nono2 = 'nono2';
var_dump( $obj->nono2 ); // nono2

$obj['nono3']['no'] = 'nono2';
var_dump( $obj['nono3']['no'] ); // NULL Notice: Indirect modification of overloaded element

$obj->nono3->no = 'nono2';
var_dump( $obj->nono3->no ); // NULL Notice: Indirect modification of overloaded property