Делаем умный объект из многомерного массива
С объектами работать удобнее из за их синтаксиса и потому что в них можно обрабатывать несуществующие свойства, если они запрашиваются при этом не получая никаких 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