Skip to content

Instantly share code, notes, and snippets.

@esilvajr
Last active May 23, 2020 06:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save esilvajr/26beaf1422922df320a4e108047862aa to your computer and use it in GitHub Desktop.
Save esilvajr/26beaf1422922df320a4e108047862aa to your computer and use it in GitHub Desktop.
This is a basic solution when we need to convert a array of objects into a multidimensional array in PHP.

Convertendo um array de objetos em array multidimensional

Algumas vezes nos deparamos com algumas responses de API ou mesmo algum cenário, onde  temos um array com vários objetos . E isso pode causar alguns problemas - como por exemplo - utilizar uma biblioteca que requer um array multidimensional como parâmetro ou converter para json. Em um cenário onde temos um array de objetos, cujos atributos são todos públicos, a solução seria:

$converted = array();
array_walk_recursive($this->array, function(&$item, $key) use (&$converted) {
	if (is_object($item)){
		$converted = get_object_vars($item);
	}
});

Caminhamos recursivamente pelo array aplicando funções aos membros do array identificados como objeto, após essa etapa atribuimos um novo array a uma variavel onde serão armazenados os objetos convertidos. Utilizando a função get_object_vars() conseguimos acessar todas as propriedades públicas de um determinado objeto. Porém caso o objeto tenha propriedades privadas não termos acesso a elas, para isso, utilizaremos Reflection.

$converted = array();
$count = 0;
array_walk_recursive($this->array, function(&$item, $key) use (&$converted, &$count) {
	if (is_object($item)){
		$reflect = new ReflectionClass($item);
		foreach ($reflect->getProperties() as $propertie) {
			$propertie->setAccessible(true);
			$converted[$count][$propertie->getName()] = $propertie->getValue($item);
		}
		$count++;
	}
});

Esse cenário é um pouco diferente além do novo array atribuimos também uma variavel do tipo inteiro para representar os indices do nosso array indexado. Construimos nossa ReflectionClass passando no construtor o objeto que queremos acessar as propriedades. Então, iteramos as propriedades do objeto e configuramos cada propriedade para acessivel convertendo assim cada propriedado do objeto para um membro array.

Veja um exemplo completo: https://gist.github.com/esilvajr/26beaf1422922df320a4e108047862aa#file-convertarrayofobjectsample-php

Que seja útil no futuro...

Referencias:

<?php
/**
* Class ConvertArrayOfObjects
* This class convert an array of objects into a multidimensional array
*/
class ConvertArrayOfObjects
{
/**
* @var array
*/
private $array = array();
/**
* @var converted array
*/
private $converted = array();
/**
* Constructor
* @param $array array
*/
public function __construct(array $array = array())
{
$this->array = $array;
}
/**
* Convert an array of object that non have any private attributes.
*/
public function withNonPrivAttributes()
{
array_walk_recursive($this->array, function(&$item, $key) {
if (is_object($item)){
$this->converted[] = get_object_vars($item);
}
});
return $this->converted;
}
/**
* Convert an array of object that have private attributes.
*/
public function withPrivAttributes()
{
$count = 0;
array_walk_recursive($this->array, function(&$item, $key) use (&$count) {
if (is_object($item)){
$reflect = new ReflectionClass($item);
foreach ($reflect->getProperties() as $propertie) {
$propertie->setAccessible(true);
$this->converted[$count][$propertie->getName()] = $propertie->getValue($item);
}
$count++;
}
});
return $this->converted;
}
}
<?php
/**
* This is just a class for our tests
*/
class Foo
{
/**
* @var foo
*/
public $foo = 'foo';
/**
* @var atrribute
*/
private $attribute = 'atrribute';
/**
* Some getter and setters
*/
public function getFoo()
{
return $foo;
}
public function setFoo($foo)
{
$this->foo = $foo;
}
}
/**
* Class ConvertArrayOfObjects
* This class convert an array of objects into a multidimensional array
*/
class ConvertArrayOfObjects
{
/**
* @var array
*/
private $array = array();
/**
* @var converted array
*/
private $converted = array();
/**
* Constructor
* @param $array array
*/
public function __construct(array $array = array())
{
$this->array = $array;
}
/**
* Convert an array of object that non have any private attributes.
*/
public function withNonPrivAttributes()
{
array_walk_recursive($this->array, function(&$item, $key) {
if (is_object($item)){
$this->converted[] = get_object_vars($item);
}
});
return $this->converted;
}
/**
* Convert an array of object that have private attributes.
*/
public function withPrivAttributes()
{
$count = 0;
array_walk_recursive($this->array, function(&$item, $key) use (&$count) {
if (is_object($item)){
$reflect = new ReflectionClass($item);
foreach ($reflect->getProperties() as $propertie) {
$propertie->setAccessible(true);
$this->converted[$count][$propertie->getName()] = $propertie->getValue($item);
}
$count++;
}
});
return $this->converted;
}
}
// Create a foo object
$foo = new Foo();
// Create a foo object with bar in foo attribute.
$bar = new Foo();
$bar->setFoo('bar');
// Create a array of objects
$array = [$foo, $bar];
$converter = new ConvertArrayOfObjects($array);
var_dump($converter->withNonPrivAttributes());
// Output:
// array (size=2)
// 0 =>
// array (size=1)
// 'foo' => string 'foo' (length=3)
// 1 =>
// array (size=1)
// 'foo' => string 'bar' (length=3)
var_dump($converter->withPrivAttributes());
// Output
// array (size=2)
// 0 =>
// array (size=2)
// 'foo' => string 'foo' (length=3)
// 'attribute' => string 'atrribute' (length=9)
// 1 =>
// array (size=2)
// 'foo' => string 'bar' (length=3)
// 'attribute' => string 'atrribute' (length=9)
@ipokkel
Copy link

ipokkel commented May 23, 2020

Thank you for sharing this class @esilvajr, came in really handy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment