web-dev-qa-db-fra.com

PHP - Tableau récursif à objet?

Existe-t-il un moyen de convertir une array multidimensionnelle en un objet stdClass en PHP?

La conversion en (object) ne semble pas fonctionner de manière récursive. json_decode(json_encode($array)) donne le résultat que je recherche, mais il doit y avoir un meilleur moyen ...

33
Peter

Autant que je sache, il n’existe pas de solution préconfigurée, vous pouvez donc lancer la vôtre:

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;
} 
55
Jacob Relkin

Je sais que cette réponse arrive en retard, mais je la posterai pour tous ceux qui recherchent une solution.

Au lieu de tout cela en boucle, etc., vous pouvez utiliser la fonction native json_ * de PHP. J'ai quelques fonctions pratiques que j'utilise beaucoup

/**
 * 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;
}

J'espère que cela peut être utile

34
Ole
function toObject($array) {
    $obj = new stdClass();
    foreach ($array as $key => $val) {
        $obj->$key = is_array($val) ? toObject($val) : $val;
    }
    return $obj;
}
7
Priya
/**
 * 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;
} 
3
Dmitriy Sintsov

Le moyen le plus simple de convertir un tableau associatif en objet est le suivant:

Commencez par l’encoder en json, puis décodez-le.

comme $objectArray = json_decode(json_encode($associtiveArray));

3
Sunil
public static function _arrayToObject($array) {
    $json = json_encode($array);
    $object = json_decode($json);
    return $object
}
2
Visakh B Sujathan

Certaines des autres solutions publiées ici ne permettent pas de distinguer les tableaux séquentiels (ce qui serait [] en JS) des cartes ({} en JS.) Dans de nombreux cas d'utilisation, il est important de distinguer les tableaux PHP comportant toutes les clés numériques séquentielles. , qui doivent être laissés tels quels, à partir de tableaux PHP ne contenant pas de clé numérique, qui doivent être convertis en objets. (Mes solutions ci-dessous ne sont pas définies pour les tableaux qui n'entrent pas dans les deux catégories ci-dessus.)

La méthode json_decode(json_encode($x)) gère correctement les deux types, mais n’est pas la solution la plus rapide. Cependant, il reste correct, totalisant25µs par analyse sur les données de mon échantillon (moyenne calculée sur 1 million d'analyses, moins le temps système de la boucle.)

J'ai comparé quelques variations du convertisseur récursif et j'ai obtenu les résultats suivants. Il reconstruit tous les tableaux et tous les objets (en effectuant une copie en profondeur), mais semble être plus rapide que les solutions alternatives qui modifient les tableaux en place. Il horloge à 11µs par exécution sur mes données d'échantillon:

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);
    }
}

Voici une version sur place. Cela peut être plus rapide sur certaines grandes données d'entrée où seules de petites pièces doivent être converties, mais sur mes données d'échantillon, cela a pris 15µs par exécution:

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;
    }
}

Je n'ai pas essayé de solutions en utilisant array_walk_recursive()

2
Tobia

Vous pouvez utiliser le array_map de manière récursive:

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

Fonctionne parfaitement pour moi, car il ne convertit pas, par exemple, les objets Carbon dans une base stdClass (ce que fait json encoder/décoder)

2
Arno van Oordt

Le plus court je pourrais venir avec:

array_walk_recursive($obj, function (&$val) { if (is_object($val)) $val = get_object_vars($val); });
0
felixfbecker

Voici une fonction permettant d'effectuer une conversion profonde en place de tableau à objet en utilisant le mécanisme de transtypage PHP interne (peu profond) de type tableau à objet . Elle crée de nouveaux objets uniquement lorsque cela est nécessaire, ce qui permet de réduire au minimum la duplication des données. .

function toObject($array) {
    foreach ($array as $key=>$value)
        if (is_array($value))
            $array[$key] = toObject($value);
    return (object)$array;
}

Attention - n'utilisez pas ce code s'il y a un risque d'avoir des références circulaires.

0
rustyx

EDIT: Cette fonction est une conversion d'objet en tableau.

De https://forrst.com/posts/PHP_Recursive_Object_to_Array_good_for_handling-0ka

protected function object_to_array($obj)
{
    $arrObj = is_object($obj) ? get_object_vars($obj) : $obj;
    foreach ($arrObj as $key => $val) {
            $val = (is_array($val) || is_object($val)) ? $this->object_to_array($val) : $val;
            $arr[$key] = $val;
    }
    return $arr;
}
0
Kamil

En retard, mais je voulais juste mentionner que vous pouvez utiliser l'encodage/décodage JSON pour convertir entièrement à partir de/en tableau

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

les fonctions json_encode et json_decode sont disponibles à partir de php 5.2

0
mhh1422

De nombreux autres utilisateurs ont indiqué les fonctions intégrées à JSON, json_decode() et json_encode() . La méthode que vous avez mentionnée fonctionne, mais pas complètement: elle ne convertira pas les tableaux indexés en objets et restera sous la forme de tableaux indexés. Cependant, il existe un truc pour surmonter ce problème. Vous pouvez utiliser JSON_FORCE_OBJECT constante:

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

Astuce: comme mentionné ici , vous pouvez convertir un objet en tableau de manière récursive à l'aide de fonctions JSON:

// Converts an object to an array recursively
$array = json_decode(json_encode($object), true));    
0
MAChitgarha

Voici une méthode simple qui peut gérer un tableau associatif avec une grande profondeur et ne pas écraser les propriétés d'objet qui ne sont pas dans le tableau.

    <?php

    function setPropsViaArray( $a, $o )
    {
        foreach ( $a as $k => $v )
        {
            if ( is_array( $v ) )
            {
                $o->{$k} = setPropsViaArray( $v, ! empty ( $o->{$k} ) ? $o->{$k} : new stdClass() );
            }
            else
            {
                $o->{$k} = $v;
            }
        }
        return $o;
    };

    setPropsViaArray( $newArrayData, $existingObject );
0
John Foley