PHP - рекурсивный массив для объекта? - PullRequest
34 голосов
/ 25 января 2011

Есть ли способ преобразовать многомерный array в stdClass объект в PHP?

Преобразование в (object), похоже, не работает рекурсивно. json_decode(json_encode($array)) дает результат, который я ищу, но должен быть лучший способ ...

Ответы [ 14 ]

55 голосов
/ 25 января 2011

Насколько я могу судить, для этого не существует готового решения, поэтому вы можете просто свернуть свое собственное:

function array_to_object($array) {
  $obj = new stdClass;
  foreach($array as $k => $v) {
     if(strlen($k)) {
        if(is_array($v)) {
           $obj->{$k} = array_to_object($v); //RECURSION
        } else {
           $obj->{$k} = $v;
        }
     }
  }
  return $obj;
} 
36 голосов
/ 08 февраля 2012

Я знаю, что этот ответ опаздывает, но я опубликую его для всех, кто ищет решение.

Вместо всех этих циклов и т. Д. Вы можете использовать встроенную в PHP функцию json_ *.У меня есть несколько удобных функций, которые я часто использую

/**
 * Convert an array into a stdClass()
 * 
 * @param   array   $array  The array we want to convert
 * 
 * @return  object
 */
function arrayToObject($array)
{
    // First we convert the array to a json string
    $json = json_encode($array);

    // The we convert the json string to a stdClass()
    $object = json_decode($json);

    return $object;
}


/**
 * Convert a object to an array
 * 
 * @param   object  $object The object we want to convert
 * 
 * @return  array
 */
function objectToArray($object)
{
    // First we convert the object into a json string
    $json = json_encode($object);

    // Then we convert the json string to an array
    $array = json_decode($json, true);

    return $array;
}

Надеюсь, это может быть полезно

7 голосов
/ 02 августа 2011
function toObject($array) {
    $obj = new stdClass();
    foreach ($array as $key => $val) {
        $obj->$key = is_array($val) ? toObject($val) : $val;
    }
    return $obj;
}
3 голосов
/ 08 февраля 2014
/**
 * Recursively converts associative arrays to stdClass while keeping integer keys subarrays as arrays
 * (lists of scalar values or collection of objects).
 */
function a2o( array $array ) {
    $resultObj = new \stdClass;
    $resultArr = array();
    $hasIntKeys = false;
    $hasStrKeys = false;
    foreach ( $array as $k => $v ) {
        if ( !$hasIntKeys ) {
            $hasIntKeys = is_int( $k );
        }
        if ( !$hasStrKeys ) {
            $hasStrKeys = is_string( $k );
        }
        if ( $hasIntKeys && $hasStrKeys ) {
            $e = new \Exception( 'Current level has both integer and string keys, thus it is impossible to keep array or convert to object' );
            $e->vars = array( 'level' => $array );
            throw $e;
        }
        if ( $hasStrKeys ) {
            $resultObj->{$k} = is_array( $v ) ? a2o( $v ) : $v;
        } else {
            $resultArr[$k] = is_array( $v ) ? a2o( $v ) : $v;
        }
    }
    return ($hasStrKeys) ? $resultObj : $resultArr;
} 
2 голосов
/ 29 июня 2018

Самый простой способ преобразовать ассоциативный массив в объект:

Сначала закодируйте его в json, а затем расшифруйте.

как $objectArray = json_decode(json_encode($associtiveArray));

2 голосов
/ 24 января 2018
public static function _arrayToObject($array) {
    $json = json_encode($array);
    $object = json_decode($json);
    return $object
}
2 голосов
/ 11 ноября 2017

Вы можете использовать array_map рекурсивно:

public static function _arrayToObject($array) {
    return is_array($array) ? (object) array_map([__CLASS__, __METHOD__], $array) : $array;
}

Прекрасно работает для меня, поскольку он не приводит, например, объекты Carbon к базовому классу stdClass (что делает кодирование / декодирование json)

2 голосов
/ 14 ноября 2016

Некоторые другие решения, опубликованные здесь, не могут отличить последовательные массивы (что будет [] в JS) от карт ({} в JS.) Для многих случаев использования важно отличать PHP-массивы, которые имеют всепоследовательные числовые ключи, которые следует оставить как таковые, из массивов PHP, которые не имеют числовых ключей, которые должны быть преобразованы в объекты.(Мои решения ниже не определены для массивов, которые не попадают в две вышеупомянутые категории.)

Метод json_decode(json_encode($x)) действительно обрабатывает два типа правильно, но это не самое быстрое решение.Тем не менее, он по-прежнему приличный, составляя 25 мкс за прогон для моих выборочных данных (в среднем за 1M прогонов, минус накладные расходы цикла).со следующим.Он перестраивает все массивы и объекты (выполняет глубокое копирование), но, похоже, работает быстрее, чем альтернативные решения, которые модифицируют существующие массивы.Он показывает 11 мкс за исполнение на моих образцах данных:

function array_to_object($x) {
    if (!is_array($x)) {
        return $x;
    } elseif (is_numeric(key($x))) {
        return array_map(__FUNCTION__, $x);
    } else {
        return (object) array_map(__FUNCTION__, $x);
    }
}

Вот версия на месте.Это может быть быстрее для некоторых больших входных данных, где нужно преобразовать только небольшие части, но в моих выборочных данных это заняло 15 мкс за выполнение:

function array_to_object_inplace(&$x) {
    if (!is_array($x)) {
        return;
    }
    array_walk($x, __FUNCTION__);
    reset($x);
    if (!is_numeric(key($x))) {
        $x = (object) $x;
    }
}

Я не пробовал решенияиспользуя array_walk_recursive()

1 голос
/ 06 января 2019

Вы и многие другие указали на встроенные функции JSON: json_decode() и json_encode(). Упомянутый вами метод работает, но не полностью: он не будет преобразовывать индексированные массивы в объекты, и они будут оставаться в виде индексированных массивов. Однако, есть выход для преодоления этой проблемы. Вы можете использовать JSON_FORCE_OBJECT константа:

// Converts an array to an object recursively
$object = json_decode(json_encode($array, JSON_FORCE_OBJECT));

Совет : Кроме того, как уже упоминалось здесь , вы можете рекурсивно преобразовать объект в массив, используя функции JSON:

// Converts an object to an array recursively
$array = json_decode(json_encode($object), true));    
0 голосов
/ 17 января 2017

Поздно, но просто хотел упомянуть, что вы можете использовать кодирование / декодирование JSON для полного преобразования из / в массив:

//convert object $object into array
$array = json_decode(json_encode($object), true);
//convert array $array into object
$object = json_decode(json_encode($array));

Функции json_encode и json_decode доступны начиная с php 5.2

...