我正在集成一个API到我的网站,它与存储在对象中的数据一起工作,而我的代码是使用数组编写的。
我想要一个快速和肮脏的函数将对象转换为数组。
我正在集成一个API到我的网站,它与存储在对象中的数据一起工作,而我的代码是使用数组编写的。
我想要一个快速和肮脏的函数将对象转换为数组。
当前回答
您还可以使用Symfony Serializer组件
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
$array = json_decode($serializer->serialize($object, 'json'), true);
其他回答
这里我创建了一个objectToArray()方法,它也适用于递归对象,比如当$objectA包含$objectB时,$objectB再次指向$objectA。
另外,我使用ReflectionClass将输出限制为公共属性。如果你不需要,就把它扔掉。
/**
* Converts given object to array, recursively.
* Just outputs public properties.
*
* @param object|array $object
* @return array|string
*/
protected function objectToArray($object) {
if (in_array($object, $this->usedObjects, TRUE)) {
return '**recursive**';
}
if (is_array($object) || is_object($object)) {
if (is_object($object)) {
$this->usedObjects[] = $object;
}
$result = array();
$reflectorClass = new \ReflectionClass(get_class($this));
foreach ($object as $key => $value) {
if ($reflectorClass->hasProperty($key) && $reflectorClass->getProperty($key)->isPublic()) {
$result[$key] = $this->objectToArray($value);
}
}
return $result;
}
return $object;
}
为了识别已经使用的对象,我在这个(抽象)类中使用了一个受保护的属性,名为$this->usedObjects。如果找到一个递归嵌套对象,它将被字符串**recursive**替换。否则会因为无限循环而失败。
对于您的情况,如果您使用“装饰器”或“日期模型转换”模式是正确的/漂亮的。例如:
你的模型
class Car {
/** @var int */
private $color;
/** @var string */
private $model;
/** @var string */
private $type;
/**
* @return int
*/
public function getColor(): int
{
return $this->color;
}
/**
* @param int $color
* @return Car
*/
public function setColor(int $color): Car
{
$this->color = $color;
return $this;
}
/**
* @return string
*/
public function getModel(): string
{
return $this->model;
}
/**
* @param string $model
* @return Car
*/
public function setModel(string $model): Car
{
$this->model = $model;
return $this;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
* @return Car
*/
public function setType(string $type): Car
{
$this->type = $type;
return $this;
}
}
装饰
class CarArrayDecorator
{
/** @var Car */
private $car;
/**
* CarArrayDecorator constructor.
* @param Car $car
*/
public function __construct(Car $car)
{
$this->car = $car;
}
/**
* @return array
*/
public function getArray(): array
{
return [
'color' => $this->car->getColor(),
'type' => $this->car->getType(),
'model' => $this->car->getModel(),
];
}
}
使用
$car = new Car();
$car->setType('type#');
$car->setModel('model#1');
$car->setColor(255);
$carDecorator = new CarArrayDecorator($car);
$carResponseData = $carDecorator->getArray();
这样代码就会更漂亮,更正确。
下面是一些代码:
function object_to_array($data) {
if ((! is_array($data)) and (! is_object($data)))
return 'xxx'; // $data;
$result = array();
$data = (array) $data;
foreach ($data as $key => $value) {
if (is_object($value))
$value = (array) $value;
if (is_array($value))
$result[$key] = object_to_array($value);
else
$result[$key] = $value;
}
return $result;
}
Use:
function readObject($object) {
$name = get_class ($object);
$name = str_replace('\\', "\\\\", $name); // Outcomment this line, if you don't use
// class namespaces approach in your project
$raw = (array)$object;
$attributes = array();
foreach ($raw as $attr => $val) {
$attributes[preg_replace('('.$name.'|\*|)', '', $attr)] = $val;
}
return $attributes;
}
它返回一个没有特殊字符和类名的数组。
class Test{
const A = 1;
public $b = 'two';
private $c = test::A;
public function __toArray(){
return call_user_func('get_object_vars', $this);
}
}
$my_test = new Test();
var_dump((array)$my_test);
var_dump($my_test->__toArray());
输出
array(2) {
["b"]=>
string(3) "two"
["Testc"]=>
int(1)
}
array(1) {
["b"]=>
string(3) "two"
}