我正在集成一个API到我的网站,它与存储在对象中的数据一起工作,而我的代码是使用数组编写的。
我想要一个快速和肮脏的函数将对象转换为数组。
我正在集成一个API到我的网站,它与存储在对象中的数据一起工作,而我的代码是使用数组编写的。
我想要一个快速和肮脏的函数将对象转换为数组。
当前回答
get_object_vars($obj)怎么样?如果您只想访问对象的公共属性,它似乎很有用。
看到get_object_vars。
其他回答
从第一个谷歌点击“PHP对象到assoc数组”,我们有:
function object_to_array($data)
{
if (is_array($data) || is_object($data))
{
$result = [];
foreach ($data as $key => $value)
{
$result[$key] = (is_array($value) || is_object($value)) ? object_to_array($value) : $value;
}
return $result;
}
return $data;
}
来源是codesnippets.joyent.com。
与json_decode和json_encode的解决方案相比,这个解决方案似乎更快。下面是一个随机的基准测试(使用简单的时间测量):
$obj = (object) [
'name' =>'Mike',
'surname' =>'Jovanson',
'age' =>'45',
'time' =>1234567890,
'country' =>'Germany',
];
##### 100 000 cycles ######
* json_decode(json_encode($var)) : 4.15 sec
* object_to_array($var) : 0.93 sec
首先,如果你需要一个来自对象的数组,你可能应该首先将数据构成一个数组。想想看。
不要使用foreach语句或JSON转换。如果您计划这样做,同样是在处理数据结构,而不是对象。
如果你真的需要它,可以使用面向对象的方法来获得干净和可维护的代码。例如:
对象作为数组
class PersonArray implements \ArrayAccess, \IteratorAggregate
{
public function __construct(Person $person) {
$this->person = $person;
}
// ...
}
如果你需要所有的属性,使用一个传输对象:
class PersonTransferObject
{
private $person;
public function __construct(Person $person) {
$this->person = $person;
}
public function toArray() {
return [
// 'name' => $this->person->getName();
];
}
}
我认为使用trait来存储对象到数组的转换逻辑是一个不错的想法。举个简单的例子:
trait ArrayAwareTrait
{
/**
* Return list of Entity's parameters
* @return array
*/
public function toArray()
{
$props = array_flip($this->getPropertiesList());
return array_map(
function ($item) {
if ($item instanceof \DateTime) {
return $item->format(DATE_ATOM);
}
return $item;
},
array_filter(get_object_vars($this), function ($key) use ($props) {
return array_key_exists($key, $props);
}, ARRAY_FILTER_USE_KEY)
);
}
/**
* @return array
*/
protected function getPropertiesList()
{
if (method_exists($this, '__sleep')) {
return $this->__sleep();
}
if (defined('static::PROPERTIES')) {
return static::PROPERTIES;
}
return [];
}
}
class OrderResponse
{
use ArrayAwareTrait;
const PROP_ORDER_ID = 'orderId';
const PROP_TITLE = 'title';
const PROP_QUANTITY = 'quantity';
const PROP_BUYER_USERNAME = 'buyerUsername';
const PROP_COST_VALUE = 'costValue';
const PROP_ADDRESS = 'address';
private $orderId;
private $title;
private $quantity;
private $buyerUsername;
private $costValue;
private $address;
/**
* @param $orderId
* @param $title
* @param $quantity
* @param $buyerUsername
* @param $costValue
* @param $address
*/
public function __construct(
$orderId,
$title,
$quantity,
$buyerUsername,
$costValue,
$address
) {
$this->orderId = $orderId;
$this->title = $title;
$this->quantity = $quantity;
$this->buyerUsername = $buyerUsername;
$this->costValue = $costValue;
$this->address = $address;
}
/**
* @inheritDoc
*/
public function __sleep()
{
return [
static::PROP_ORDER_ID,
static::PROP_TITLE,
static::PROP_QUANTITY,
static::PROP_BUYER_USERNAME,
static::PROP_COST_VALUE,
static::PROP_ADDRESS,
];
}
/**
* @return mixed
*/
public function getOrderId()
{
return $this->orderId;
}
/**
* @return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* @return mixed
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* @return mixed
*/
public function getBuyerUsername()
{
return $this->buyerUsername;
}
/**
* @return mixed
*/
public function getCostValue()
{
return $this->costValue;
}
/**
* @return string
*/
public function getAddress()
{
return $this->address;
}
}
$orderResponse = new OrderResponse(...);
var_dump($orderResponse->toArray());
自定义函数将stdClass转换为数组:
function objectToArray($d) {
if (is_object($d)) {
// Gets the properties of the given object
// with get_object_vars function
$d = get_object_vars($d);
}
if (is_array($d)) {
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return array_map(__FUNCTION__, $d);
} else {
// Return array
return $d;
}
}
另一个将Array转换为stdClass的自定义函数:
function arrayToObject($d) {
if (is_array($d)) {
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return (object) array_map(__FUNCTION__, $d);
} else {
// Return object
return $d;
}
}
使用的例子:
// Create new stdClass Object
$init = new stdClass;
// Add some test data
$init->foo = "Test data";
$init->bar = new stdClass;
$init->bar->baaz = "Testing";
$init->bar->fooz = new stdClass;
$init->bar->fooz->baz = "Testing again";
$init->foox = "Just test";
// Convert array to object and then object back to array
$array = objectToArray($init);
$object = arrayToObject($array);
// Print objects and array
print_r($init);
echo "\n";
print_r($array);
echo "\n";
print_r($object);
这里发布的所有其他答案都只使用公共属性。下面是一个使用反射和getter处理类javabean对象的解决方案:
function entity2array($entity, $recursionDepth = 2) {
$result = array();
$class = new ReflectionClass(get_class($entity));
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
$methodName = $method->name;
if (strpos($methodName, "get") === 0 && strlen($methodName) > 3) {
$propertyName = lcfirst(substr($methodName, 3));
$value = $method->invoke($entity);
if (is_object($value)) {
if ($recursionDepth > 0) {
$result[$propertyName] = $this->entity2array($value, $recursionDepth - 1);
}
else {
$result[$propertyName] = "***"; // Stop recursion
}
}
else {
$result[$propertyName] = $value;
}
}
}
return $result;
}