Comment convertir un tableau en objet en PHP?
Comment puis-je convertir un tableau comme celui-ci en objet?
[128] => Array ( [status] => Figure A. Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution. ) [129] => Array ( [status] => The other day at work, I had some spare time ) )
30 réponses
Dans le cas le plus simple, il suffit probablement de "lancer" le tableau en tant qu'objet:
$object = (object) $array;
Une autre option serait d'instancier une classe standard en tant que variable, et de parcourir votre tableau tout en réattribuant les valeurs:
$object = new stdClass();
foreach ($array as $key => $value)
{
$object->$key = $value;
}
Comme Edson Médina souligné, vraiment propre solution est d'utiliser le haut-json_
fonctions:
$object = json_decode(json_encode($array), FALSE);
Cela convertit également (récursivement) tous vos sous-tableaux en objets, que vous pouvez ou non vouloir. Malheureusement, il a un 2-3x performances sur la boucle de la démarche.
Attention! (Merci à Ultra pour le commentaire):
Json_decode sur différents environnements convertit les données UTF-8 de différentes manières. Je finis par obtenir des valeurs '240.00' localement et ' 240 ' sur la production-dissaster massif. Morover si la conversion échoue string get est renvoyé comme NULL
Vous pouvez simplement utiliser le casting de type pour convertir un tableau en objet.
// *convert array to object* Array([id]=> 321313[username]=>shahbaz)
$object = (object) $array_name;
//now it is converted to object and you can access it.
echo $object->username;
Voici trois façons:
-
Faux un objet réel:
class convert { public $varible; public function __construct($array) { $this = $array; } public static function toObject($array) { $array = new convert($array); return $array; } }
-
Convertissez le tableau en objet en le convertissant en objet:
$array = array( // ... ); $object = (object) $array;
-
Convertir manuellement le tableau en objet:
$object = object; foreach ($arr as $key => $value) { $object->{$key} = $value; }
Hack rapide:
// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);
Pas joli, mais fonctionne.
Le moyen facile serait
$object = (object)$array;
, Mais ce n'est pas ce que vous voulez. Si vous voulez des objets, vous voulez réaliser quelque chose, mais cela manque dans cette question. Utiliser des objets juste pour la raison d'utiliser des objets n'a aucun sens.
Sa façon de simple, Cela va créer un objet pour les tableaux:
$object = json_decode(json_encode((object) $yourArray), FALSE);
Selon l'endroit où vous en avez besoin et comment accéder à l'objet, il existe différentes façons de le faire.
Par exemple: il suffit de le typecast
$object = (object) $yourArray;
Cependant, le plus compatible utilise une méthode utilitaire (qui ne fait pas encore partie de PHP) qui implémente le casting PHP standard basé sur une chaîne qui spécifie le type (ou en l'ignorant simplement en déséférençant la valeur):
/**
* dereference a value and optionally setting its type
*
* @param mixed $mixed
* @param null $type (optional)
*
* @return mixed $mixed set as $type
*/
function rettype($mixed, $type = NULL) {
$type === NULL || settype($mixed, $type);
return $mixed;
}
L'exemple d'utilisation dans votre cas (Démo en Ligne):
$yourArray = Array('status' => 'Figure A. ...');
echo rettype($yourArray, 'object')->status; // prints "Figure A. ..."
Celui-ci a fonctionné pour moi
function array_to_obj($array, &$obj)
{
foreach ($array as $key => $value)
{
if (is_array($value))
{
$obj->$key = new stdClass();
array_to_obj($value, $obj->$key);
}
else
{
$obj->$key = $value;
}
}
return $obj;
}
function arrayToObject($array)
{
$object= new stdClass();
return array_to_obj($array,$object);
}
Utilisation :
$myobject = arrayToObject($array);
print_r($myobject);
Retourne :
[127] => stdClass Object
(
[status] => Have you ever created a really great looking website design
)
[128] => stdClass Object
(
[status] => Figure A.
Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution.
)
[129] => stdClass Object
(
[status] => The other day at work, I had some spare time
)
Comme d'habitude, vous pouvez faire une boucle comme:
foreach($myobject as $obj)
{
echo $obj->status;
}
Il N'y a pas de méthode intégrée pour le faire autant que je sache, mais c'est aussi simple qu'une simple boucle:
$obj= new stdClass();
foreach ($array as $k=> $v) {
$obj->{$k} = $v;
}
Vous pouvez expliquer cela si vous en avez besoin pour construire votre objet récursivement.
En fait, si vous voulez l'utiliser avec des tableaux multidimensionnels, vous voudriez utiliser une récursivité.
static public function array_to_object(array $array)
{
foreach($array as $key => $value)
{
if(is_array($value))
{
$array[$key] = self::array_to_object($value);
}
}
return (object)$array;
}
J'irais certainement avec une manière propre comme ceci:
<?php
class Person {
private $name;
private $age;
private $sexe;
function __construct ($payload)
{
if (is_array($payload))
$this->from_array($payload);
}
public function from_array($array)
{
foreach(get_object_vars($this) as $attrName => $attrValue)
$this->{$attrName} = $array[$attrName];
}
public function say_hi ()
{
print "hi my name is {$this->name}";
}
}
print_r($_POST);
$mike = new Person($_POST);
$mike->say_hi();
?>
Si vous soumettez:
, Vous obtiendrez ceci:
J'ai trouvé cela plus logique en comparant les réponses ci-dessus des objets devraient être utilisés dans le but pour lequel ils ont été faits (petits objets mignons encapsulés).
En utilisant également get_object_vars, assurez-vous qu'aucun attribut supplémentaire n'est créé dans l'objet manipulé (vous ne voulez pas qu'une voiture ait un nom de famille, ni qu'une personne se comporte 4 roue).
La récursivité est votre ami:
function __toObject(Array $arr) {
$obj = new stdClass();
foreach($arr as $key=>$val) {
if (is_array($val)) {
$val = __toObject($val);
}
$obj->$key = $val;
}
return $obj;
}
Facile:
$object = json_decode(json_encode($array));
Exemple:
$array = array(
'key' => array(
'k' => 'value',
),
'group' => array('a', 'b', 'c')
);
$object = json_decode(json_encode($array));
Alors, ce qui suit est vrai:
$object->key->k === 'value';
$object->group === array('a', 'b', 'c')
Vous pouvez également utiliser un ArrayObject, par exemple:
<?php
$arr = array("test",
array("one"=>1,"two"=>2,"three"=>3),
array("one"=>1,"two"=>2,"three"=>3)
);
$o = new ArrayObject($arr);
echo $o->offsetGet(2)["two"],"\n";
foreach ($o as $key=>$val){
if (is_array($val)) {
foreach($val as $k => $v) {
echo $k . ' => ' . $v,"\n";
}
}
else
{
echo $val,"\n";
}
}
?>
//Output:
2
test
one => 1
two => 2
three => 3
one => 1
two => 2
three => 3
Celui que j'utilise (c'est un membre de la classe):
const MAX_LEVEL = 5; // change it as needed
public function arrayToObject($a, $level=0)
{
if(!is_array($a)) {
throw new InvalidArgumentException(sprintf('Type %s cannot be cast, array expected', gettype($a)));
}
if($level > self::MAX_LEVEL) {
throw new OverflowException(sprintf('%s stack overflow: %d exceeds max recursion level', __METHOD__, $level));
}
$o = new stdClass();
foreach($a as $key => $value) {
if(is_array($value)) { // convert value recursively
$value = $this->arrayToObject($value, $level+1);
}
$o->{$key} = $value;
}
return $o;
}
Utilisez cette fonction que j'ai faite:
function buildObject($class,$data){
$object = new $class;
foreach($data as $key=>$value){
if(property_exists($class,$key)){
$object->{'set'.ucfirst($key)}($value);
}
}
return $object;
}
Utilisation:
$myObject = buildObject('MyClassName',$myArray);
Technique peu compliquée mais facile à étendre:
Supposons que vous ayez un tableau
$a = [
'name' => 'ankit',
'age' => '33',
'dob' => '1984-04-12'
];
Supposons que vous ayez une classe person qui peut avoir plus ou moins d'attributs de ce tableau. par exemple
class Person
{
private $name;
private $dob;
private $age;
private $company;
private $city;
}
Si vous voulez toujours changer votre tableau en objet person. Vous pouvez utiliser la classe ArrayIterator.
$arrayIterator = new \ArrayIterator($a); // Pass your array in the argument.
Maintenant, vous avez l'objet iterator.
Créez une classe étendant la classe FilterIterator; où vous devez définir la méthode abstraite accept. Suivez les exemple
class PersonIterator extends \FilterIterator
{
public function accept()
{
return property_exits('Person', parent::current());
}
}
L'impelmentation ci-dessus ne liera la propriété que si elle existe dans la classe.
Ajoutez une méthode supplémentaire dans la classe PersonIterator
public function getObject(Person $object)
{
foreach ($this as $key => $value)
{
$object->{'set' . underscoreToCamelCase($key)}($value);
}
return $object;
}
Assurez-vous que vous avez des mutateurs définis dans votre classe. Maintenant, vous êtes prêt à appeler ces fonctions où vous voulez créer un objet.
$arrayiterator = new \ArrayIterator($a);
$personIterator = new \PersonIterator($arrayiterator);
$personIterator->getObject(); // this will return your Person Object.
Vous pouvez également le faire en ajoutant (object) à gauche de la variable pour créer un nouvel objet.
<?php
$a = Array
( 'status' => " text" );
var_dump($a);
$b = (object)$a;
var_dump($b);
var_dump($b->status);
L'utilisation de json_encode
est problématique en raison de la façon dont elle gère les données non UTF-8. Il est à noter que le json_encode
/json_encode
la méthode laisse également des tableaux non associatifs en tant que tableaux. Cela peut ou peut ne pas être ce que vous voulez. J'étais récemment dans la position de devoir recréer les fonctionnalités de cette solution mais sans utiliser les fonctions json_
. Voici ce que je suis venu avec:
/**
* Returns true if the array has only integer keys
*/
function isArrayAssociative(array $array) {
return (bool)count(array_filter(array_keys($array), 'is_string'));
}
/**
* Converts an array to an object, but leaves non-associative arrays as arrays.
* This is the same logic that `json_decode(json_encode($arr), false)` uses.
*/
function arrayToObject(array $array, $maxDepth = 10) {
if($maxDepth == 0) {
return $array;
}
if(isArrayAssociative($array)) {
$newObject = new \stdClass;
foreach ($array as $key => $value) {
if(is_array($value)) {
$newObject->{$key} = arrayToObject($value, $maxDepth - 1);
} else {
$newObject->{$key} = $value;
}
}
return $newObject;
} else {
$newArray = array();
foreach ($array as $value) {
if(is_array($value)) {
$newArray[] = arrayToObject($value, $maxDepth - 1);
} else {
$newArray[] = $value;
}
}
return $newArray;
}
}
Meilleure méthode dans le Monde:)
function arrayToObject($conArray)
{
if(is_array($conArray)){
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return (object) array_map(__FUNCTION__, $conArray);
}else{
// Return object
return $conArray;
}
}
Si vous utilisez des méthodes différentes, vous aurez des problèmes. C'est la meilleure méthode. Vous avez jamais vu.
Une doublure
$object= json_decode(json_encode($result_array, JSON_FORCE_OBJECT));
Cela nécessite PHP7 car j'ai choisi d'utiliser une fonction lambda pour verrouiller le 'innerfunc' dans la fonction principale. La fonction lambda est appelée récursivement, d'où la nécessité de: "use (&$innerfunc)". Vous pouvez le faire en PHP5 mais ne pouvait pas cacher le innerfunc.
function convertArray2Object($defs) {
$innerfunc = function ($a) use ( &$innerfunc ) {
return (is_array($a)) ? (object) array_map($innerfunc, $a) : $a;
};
return (object) array_map($innerfunc, $defs);
}
Évidemment, juste une extrapolation des réponses de certaines autres personnes, mais voici la fonction récursive qui convertira tout tableau dimensionnel en un objet:
function convert_array_to_object($array){
$obj= new stdClass();
foreach ($array as $k=> $v) {
if (is_array($v)){
$v = convert_array_to_object($v);
}
$obj->{strtolower($k)} = $v;
}
return $obj;
}
Et rappelez-vous que si le tableau avait des clés numériques, elles peuvent toujours être référencées dans l'objet résultant en utilisant {}
(par exemple: $obj->prop->{4}->prop
)
Inspiré par tous ces codes, j'ai essayé de créer une version améliorée avec le support de: nom de classe spécifique, éviter la méthode constructeur, motif 'beans' et mode strict (définir uniquement les propriétés existantes):
class Util {
static function arrayToObject($array, $class = 'stdClass', $strict = false) {
if (!is_array($array)) {
return $array;
}
//create an instance of an class without calling class's constructor
$object = unserialize(
sprintf(
'O:%d:"%s":0:{}', strlen($class), $class
)
);
if (is_array($array) && count($array) > 0) {
foreach ($array as $name => $value) {
$name = strtolower(trim($name));
if (!empty($name)) {
if(method_exists($object, 'set'.$name)){
$object->{'set'.$name}(Util::arrayToObject($value));
}else{
if(($strict)){
if(property_exists($class, $name)){
$object->$name = Util::arrayToObject($value);
}
}else{
$object->$name = Util::arrayToObject($value);
}
}
}
}
return $object;
} else {
return FALSE;
}
}
}
Code
Cette fonction fonctionne comme json_decode(json_encode($arr), false)
.
function arrayToObject(array $arr)
{
$flat = array_keys($arr) === range(0, count($arr) - 1);
$out = $flat ? [] : new \stdClass();
foreach ($arr as $key => $value) {
$temp = is_array($value) ? $this->arrayToObject($value) : $value;
if ($flat) {
$out[] = $temp;
} else {
$out->{$key} = $temp;
}
}
return $out;
}
Test
Test 1: Tableau plat
$arr = ["a", "b", "c"];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));
Sortie:
array(
0 => 'a',
1 => 'b',
2 => 'c',
)
array(
0 => 'a',
1 => 'b',
2 => 'c',
)
Test 2: Tableau d'objets
$arr = [["a" => 1], ["a" => 1], ["a" => 1]];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));
Sortie:
array(
0 => stdClass::__set_state(array('a' => 1,)),
1 => stdClass::__set_state(array('a' => 1,)),
2 => stdClass::__set_state(array('a' => 1,)),
)
array(
0 => stdClass::__set_state(array('a' => 1,)),
1 => stdClass::__set_state(array('a' => 1,)),
2 => stdClass::__set_state(array('a' => 1,)),
)
Test 3: Objet
$arr = ["a" => 1];
var_export(json_decode($arr));
var_export($this->arrayToObject($arr));
Sortie:
stdClass::__set_state(array('a' => 1,))
stdClass::__set_state(array('a' => 1,))
CakePHP a une classe récursive Set:: map qui mappe fondamentalement un tableau dans un objet. Vous devrez peut-être changer à quoi ressemble le tableau afin de rendre l'objet comme vous le souhaitez.
Http://api.cakephp.org/view_source/set/#line-158
Dans le pire des cas, vous pourriez être en mesure d'obtenir quelques idées de cette fonction.
Je l'ai fait avec assez simples,
$list_years = array();
$object = new stdClass();
$object->year_id = 1 ;
$object->year_name = 2001 ;
$list_years[] = $object;
function object_to_array($data)
{
if (is_array($data) || is_object($data))
{
$result = array();
foreach ($data as $key => $value)
{
$result[$key] = object_to_array($value);
}
return $result;
}
return $data;
}
function array_to_object($data)
{
if (is_array($data) || is_object($data))
{
$result= new stdClass();
foreach ($data as $key => $value)
{
$result->$key = array_to_object($value);
}
return $result;
}
return $data;
}
En utilisant (array) et (object) comme préfixe, Vous pouvez simplement convertir le tableau d'objets en tableau standard et vice-Verset
<?php
//defining an array
$a = array('a'=>'1','b'=>'2','c'=>'3','d'=>'4');
//defining an object array
$obj = new stdClass();
$obj->a = '1';
$obj->b = '2';
$obj->c = '3';
$obj->d = '4';
print_r($a);echo '<br>';
print_r($obj);echo '<br>';
//converting object array to array
$b = (array) $obj;
print_r($b);echo '<br>';
//converting array to object
$c = (object) $a;
print_r($c);echo '<br>';
?>
J'utilise ce qui suit pour analyser les tableaux associatifs des fichiers Yaml dans un État d'objet.
Cela vérifie tous les tableaux fournis s'il y a des objets qui s'y cachent, et les transforme également en objets.
/**
* Makes a config object from an array, making the first level keys properties a new object.
* Property values are converted to camelCase and are not set if one already exists.
* @param array $configArray Config array.
* @param boolean $strict To return an empty object if $configArray is not an array
* @return stdObject The config object
*/
public function makeConfigFromArray($configArray = [],$strict = true)
{
$object = new stdClass();
if (!is_array($configArray)) {
if(!$strict && !is_null($configArray)) {
return $configArray;
}
return $object;
}
foreach ($configArray as $name => $value) {
$_name = camel_case($name);
if(is_array($value)) {
$makeobject = true;
foreach($value as $key => $val) {
if(is_numeric(substr($key,0,1))) {
$makeobject = false;
}
if(is_array($val)) {
$value[$key] = $this->makeConfigFromArray($val,false);
}
}
if($makeobject) {
$object->{$name} = $object->{$_name} = $this->makeConfigFromArray($value,false);
}
else {
$object->{$name} = $object->{$_name} = $value;
}
}
else {
$object->{$name} = $object->{$_name} = $value;
}
}
return $object;
}
Cela transforme un yaml configuré comme
fields:
abc:
type: formfield
something:
- a
- b
- c
- d:
foo:
bar
À un tableau composé de:
array:1 [
"fields" => array:1 [
"abc" => array:2 [
"type" => "formfield"
"something" => array:4 [
0 => "a"
1 => "b"
2 => "c"
3 => array:1 [
"d" => array:1 [
"foo" => "bar"
]
]
]
]
]
]
À un objet de:
{#325
+"fields": {#326
+"abc": {#324
+"type": "formfield"
+"something": array:4 [
0 => "a"
1 => "b"
2 => "c"
3 => {#328
+"d": {#327
+"foo": "bar"
}
}
]
}
}
}