objetos - ¿Cómo convertir una matriz a objeto en PHP?
stdclass object to array php (30)
¿Cómo puedo convertir una matriz como esta a objeto?
[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 ) )
Código
Esta función funciona igual que 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;
}
Pruebas
Prueba 1: matriz plana
$arr = ["a", "b", "c"];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));
Salida:
array(
0 => ''a'',
1 => ''b'',
2 => ''c'',
)
array(
0 => ''a'',
1 => ''b'',
2 => ''c'',
)
Prueba 2: Arreglo de objetos
$arr = [["a" => 1], ["a" => 1], ["a" => 1]];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));
Salida:
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,)),
)
Prueba 3: Objeto
$arr = ["a" => 1];
var_export(json_decode($arr));
var_export($this->arrayToObject($arr));
Salida:
stdClass::__set_state(array(''a'' => 1,))
stdClass::__set_state(array(''a'' => 1,))
Al usar (matriz) y (objeto) como prefijo, simplemente puede convertir la matriz de objetos en una matriz estándar y viceversa
<?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>'';
?>
Aquí hay tres maneras:
Falsea un objeto real:
class convert { public $varible; public function __construct($array) { $this = $array; } public static function toObject($array) { $array = new convert($array); return $array; } }
Convierta la matriz en un objeto lanzándola a un objeto:
$array = array( // ... ); $object = (object) $array;
Convierte manualmente la matriz en un objeto:
$object = object; foreach ($arr as $key => $value) { $object->{$key} = $value; }
CakePHP tiene una clase recursiva Set :: map que básicamente asigna una matriz a un objeto. Es posible que deba cambiar el aspecto de la matriz para que el objeto tenga el aspecto deseado.
http://api.cakephp.org/view_source/set/#line-158
En el peor de los casos, puede obtener algunas ideas de esta función.
Corte rápido:
// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);
No es bonito, pero funciona.
Definitivamente me gustaría ir con una manera limpia como esta:
<?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 usted envía:
obtendrá esto:
Encontré que esto es más lógico al comparar las respuestas anteriores de los Objetos que deberían usarse para el propósito para el que fueron creados (pequeños objetos lindos encapsulados).
El uso de get_object_vars también asegura que no se creen atributos adicionales en el Objeto manipulado (no desea que un automóvil tenga un apellido, ni una persona que se comporte en 4 ruedas).
Dependiendo de dónde lo necesite y de cómo acceder al objeto, hay diferentes maneras de hacerlo.
Por ejemplo: simplemente encasilla
$object = (object) $yourArray;
Sin embargo, el más compatible es usar un método de utilidad (que aún no es parte de PHP) que implementa la conversión PHP estándar basada en una cadena que especifica el tipo (o ignorándolo simplemente desvirtuando el valor):
/**
* 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;
}
El ejemplo de uso en su caso ( Demo en línea ):
$yourArray = Array(''status'' => ''Figure A. ...'');
echo rettype($yourArray, ''object'')->status; // prints "Figure A. ..."
El mejor método en el mundo :)
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 usas diferentes métodos tendrás problemas. Este es el mejor método. Alguna vez has visto.
El que yo uso (es un miembro de la clase):
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 : %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;
}
En el caso más simple, probablemente sea suficiente para "convertir" la matriz como un objeto:
$object = (object) $array;
Otra opción sería crear una instancia de una clase estándar como una variable, y recorrer su matriz mientras reasigna los valores:
$object = new stdClass();
foreach ($array as $key => $value)
{
$object->$key = $value;
}
Como señaló Edson Medina , una solución realmente limpia es usar las funciones json_
incorporadas:
$object = json_decode(json_encode($array), FALSE);
Esto también (recursivamente) convierte todas las subarreglas en objetos, lo que puede o no desear. Desafortunadamente, tiene un éxito de rendimiento de 2-3x sobre el enfoque de bucle.
¡Advertencia! (Gracias a Ultra por el comentario):
json_decode en diferentes entornos convierte los datos UTF-8 de diferentes maneras. Terminé obteniendo valores ''240.00'' a nivel local y ''240'' en producción - desastre masivo. De nuevo si la conversión falla, la cadena se devuelve como NULL
En realidad, si desea usar esto con matrices multidimensionales, desearía usar algo de recursión.
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;
}
Es sencillo, esto también creará un objeto para matrices recursivas:
$object = json_decode(json_encode((object) $yourArray), FALSE);
Este funciono para mi
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);
}
uso:
$myobject = arrayToObject($array);
print_r($myobject);
devoluciones :
[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
)
Como de costumbre, puedes hacerlo como:
foreach($myobject as $obj)
{
echo $obj->status;
}
Esto requiere PHP7 porque elegí usar una función lambda para bloquear el ''innerfunc'' dentro de la función principal. La función lambda se llama de forma recursiva, de ahí la necesidad de: "use (& $ innerfunc)". Podrías hacerlo en PHP5 pero no pudiste ocultar el funcionamiento interno.
function convertArray2Object($defs) {
$innerfunc = function ($a) use ( &$innerfunc ) {
return (is_array($a)) ? (object) array_map($innerfunc, $a) : $a;
};
return (object) array_map($innerfunc, $defs);
}
Fácil:
$object = json_decode(json_encode($array));
Ejemplo:
$array = array(
''key'' => array(
''k'' => ''value'',
),
''group'' => array(''a'', ''b'', ''c'')
);
$object = json_decode(json_encode($array));
Entonces, lo siguiente es cierto:
$object->key->k === ''value'';
$object->group === array(''a'', ''b'', ''c'')
Inspirado por todos estos códigos, intenté crear una versión mejorada con soporte para: nombre de clase específica, método de constructor evitado, patrón ''beans'' y modo estricto (establecer solo las propiedades existentes):
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;
}
}
}
La forma más fácil sería
$object = (object)$array;
Pero eso no es lo que quieres. Si quieres objetos, quieres lograr algo, pero eso falta en esta pregunta. Usar objetos solo por la razón de usar objetos no tiene sentido.
Lo he hecho de manera bastante simple.
$list_years = array();
$object = new stdClass();
$object->year_id = 1 ;
$object->year_name = 2001 ;
$list_years[] = $object;
No hay un método integrado para hacerlo, que yo sepa, pero es tan fácil como un simple bucle:
$obj= new stdClass();
foreach ($array as $k=> $v) {
$obj->{$k} = $v;
}
Puedes explicarlo si lo necesitas para construir tu objeto recursivamente.
Obviamente, solo es una extrapolación de las respuestas de otras personas, pero aquí está la función recursiva que convertirá cualquier matriz multidimensional en un objeto:
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;
}
Y recuerde que si la matriz tenía claves numéricas, aún se puede hacer referencia en el objeto resultante utilizando {}
(por ejemplo: $obj->prop->{4}->prop
)
Técnica poco complicada pero fácil de extender:
Supongamos que tienes una matriz
$a = [
''name'' => ''ankit'',
''age'' => ''33'',
''dob'' => ''1984-04-12''
];
Supongamos que tiene una clase de persona que puede tener más o menos atributos de esta matriz. por ejemplo
class Person
{
private $name;
private $dob;
private $age;
private $company;
private $city;
}
Si todavía quieres cambiar tu matriz al objeto persona. Puedes usar ArrayIterator Class.
$arrayIterator = new /ArrayIterator($a); // Pass your array in the argument.
Ahora tienes objeto iterador.
Crear una clase extendiendo la clase FilterIterator; Donde hay que definir el método abstracto aceptar. Sigue el ejemplo
class PersonIterator extends /FilterIterator
{
public function accept()
{
return property_exists(''Person'', parent::current());
}
}
La ejecución anterior se unirá a la propiedad solo si existe en la clase.
Agrega un método más en la clase PersonIterator
public function getObject(Person $object)
{
foreach ($this as $key => $value)
{
$object->{''set'' . underscoreToCamelCase($key)}($value);
}
return $object;
}
Asegúrese de tener mutadores definidos en su clase. Ahora está listo para llamar a estas funciones donde desea crear un objeto.
$arrayiterator = new /ArrayIterator($a);
$personIterator = new /PersonIterator($arrayiterator);
$personIterator->getObject(); // this will return your Person Object.
También puede hacer esto agregando (objeto) a la izquierda de la variable para crear un nuevo objeto.
<?php
$a = Array
( ''status'' => " text" );
var_dump($a);
$b = (object)$a;
var_dump($b);
var_dump($b->status);
También puedes usar un ArrayObject, por ejemplo:
<?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
Usa esta función que he hecho:
function buildObject($class,$data){
$object = new $class;
foreach($data as $key=>$value){
if(property_exists($class,$key)){
$object->{''set''.ucfirst($key)}($value);
}
}
return $object;
}
Uso:
$myObject = buildObject(''MyClassName'',$myArray);
Usar json_encode
es problemático debido a la forma en que maneja datos que no son UTF-8. Vale la pena señalar que el método json_encode
/ json_encode
también deja matrices no asociativas como matrices. Esto puede o no ser lo que quieres. Recientemente estuve en la posición de necesitar recrear la funcionalidad de esta solución pero sin usar json_
funciones json_
. Esto es lo que se me ocurrió:
/**
* 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;
}
}
Uso lo siguiente para analizar los arreglos asociativos de archivos Yaml en un estado de objeto.
Esto verifica todas las matrices suministradas si hay objetos escondidos allí, y las convierte también en objetos.
/**
* 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;
}
Esto convierte un yaml configurado como
fields:
abc:
type: formfield
something:
- a
- b
- c
- d:
foo:
bar
a una matriz que consiste en:
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"
]
]
]
]
]
]
a un objeto de:
{#325
+"fields": {#326
+"abc": {#324
+"type": "formfield"
+"something": array:4 [
0 => "a"
1 => "b"
2 => "c"
3 => {#328
+"d": {#327
+"foo": "bar"
}
}
]
}
}
}
la recursion es tu amiga
function __toObject(Array $arr) {
$obj = new stdClass();
foreach($arr as $key=>$val) {
if (is_array($val)) {
$val = __toObject($val);
}
$obj->$key = $val;
}
return $obj;
}
simplemente puede utilizar la conversión de tipos para convertir una matriz en objeto.
// *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;
un trazador de líneas
$object= json_decode(json_encode($result_array, JSON_FORCE_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;
}