我正在将一个API集成到我的网站上,它使用存储在对象中的数据,而我的代码是使用数组编写的。
我想要一个快速且简单的函数来将对象转换为数组。
$array = (array) $yourObject;
如果一个对象被转换为数组,结果将是一个数组,其元素是对象的属性。键是成员变量名,有一些值得注意的例外:整数属性是不可访问的;私有变量在变量名前面加上类名;受保护的变量在变量名前面加上'*'。这些前置值两边都有空字节。
示例:简单对象
$object = new StdClass;
$object->foo = 1;
$object->bar = 2;
var_dump( (array) $object );
输出:
array(2) {
'foo' => int(1)
'bar' => int(2)
}
例子:复杂对象
class Foo
{
private $foo;
protected $bar;
public $baz;
public function __construct()
{
$this->foo = 1;
$this->bar = 2;
$this->baz = new StdClass;
}
}
var_dump( (array) new Foo );
输出(为了清晰起见编辑了 \0):
array(3) {
'\0Foo\0foo' => int(1)
'\0*\0bar' => int(2)
'baz' => class stdClass#2 (0) {}
}
使用var_export
而不是var_dump
输出:
array (
'' . "\0" . 'Foo' . "\0" . 'foo' => 1,
'' . "\0" . '*' . "\0" . 'bar' => 2,
'baz' =>
stdClass::__set_state(array(
)),
)
要了解更多关于 PHP 内置类 stdclass
的信息。您可以 阅读这份文档
以这种方式进行类型转换不会对对象图进行深度转换,并且您需要应用空字节(如手册中所述)才能访问任何非公共属性。因此,当转换 StdClass 对象或仅具有公共属性的对象时,此方法效果最佳。对于快速而简单(您所要求的),它是可以接受的。
还可以查看这篇深入的博客文章:
通过依靠JSON编码/解码函数的行为,您可以快速将深度嵌套的对象转换为关联数组:
$array = json_decode(json_encode($nested_object), true);
/**
* @param array|object $data
* @return array
*/
function object_to_array($data)
{
$result = [];
foreach ($data as $key => $value)
{
$result[$key] = (is_array($value) || is_object($value)) ? object_to_array($value) : $value;
}
return $result;
}
json_decode & json_encode
的解决方案进行比较,这个似乎更快。这是一个随机基准测试(使用simple time measuring):$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
function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; }
这个函数只对非对象和非数组进行转换,并且只在必要时才回到方法中,避免了重复调用。 - SpYk3HH$array = (array) $object;
如果它们是私有的或受保护的,它们在数组中将具有奇怪的键名称。因此,在这种情况下,您需要使用以下函数:
function dismount($object) {
$reflectionClass = new ReflectionClass(get_class($object));
$array = array();
foreach ($reflectionClass->getProperties() as $property) {
$property->setAccessible(true);
$array[$property->getName()] = $property->getValue($object);
$property->setAccessible(false);
}
return $array;
}
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"
}
以下是一些代码:
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;
}
$arr = (array) $Obj;
它将解决你的问题。
这里所有其他发布的答案只适用于公共属性。下面是一种使用反射和getter方法可与JavaBeans类似的对象一起使用的解决方案:
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;
}
要将对象转换为数组,只需将其显式转换:
$name_of_array = (array) $name_of_object;
ArrayAccess
接口,结合这个解决方案。http://php.net/manual/en/class.arrayaccess.php - alttag[1 => "one"]
会变成["1" => "one"]
。 - Oleg(array)
和(object)
进行类型转换在PHP 4.3及以后的所有版本中都可靠并且行为相同。请参考https://3v4l.org/X6lhm。如果出现语法错误,则说明您做错了什么。 - Gordonempty
。在5.5之前,您不能使用empty
表达式。这与类型转换完全无关 ;) - Gordon