将PHP对象转换为关联数组

Har*_*ldo 714 php arrays

我正在将API集成到我的网站,该网站使用存储在对象中的数据,而我的代码是使用数组编写的.

我想要一个快速而又脏的函数将对象转换为数组.

Gor*_*don 1313

只是强调它

$array = (array) $yourObject;
Run Code Online (Sandbox Code Playgroud)

来自http://www.php.net/manual/en/language.types.array.php

如果将对象转换为数组,则结果是一个数组,其元素是对象的属性.键是成员变量名,有一些值得注意的例外:整数属性是不可访问的; 私有变量的类名前置于变量名; 受保护的变量在变量名前面加上'*'.这些前置值在任一侧都有空字节.

示例:简单对象

$object = new StdClass;
$object->foo = 1;
$object->bar = 2;

var_dump( (array) $object );
Run Code Online (Sandbox Code Playgroud)

输出:

array(2) {
  'foo' => int(1)
  'bar' => int(2)
}
Run Code Online (Sandbox Code Playgroud)

示例:复杂对象

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 );
Run Code Online (Sandbox Code Playgroud)

输出(为清晰起见,编辑了\ 0s):

array(3) {
  '\0Foo\0foo' => int(1)
  '\0*\0bar' => int(2)
  'baz' => class stdClass#2 (0) {}
}
Run Code Online (Sandbox Code Playgroud)

输出var_export而不是var_dump:

array (
  '' . "\0" . 'Foo' . "\0" . 'foo' => 1,
  '' . "\0" . '*' . "\0" . 'bar' => 2,
  'baz' =>
  stdClass::__set_state(array(
  )),
)
Run Code Online (Sandbox Code Playgroud)

以这种方式进行类型转换不会对对象图进行深度转换,您需要应用空字节(如手册中所述)来访问任何非公共属性.因此,在仅使用公共属性转换StdClass对象或对象时,这种方法效果最佳.为了快速和肮脏(你要求的)它没关系.

另见这篇深入的博文:

  • 如果您有整数键,它们将被转换为字符串,这可能会导致大问题。例如`[1 => "one"]`变成`["1" => "one"]` (4认同)
  • @Howie Typecasting with `(array)` 和 `(object)` 工作可靠,自 PHP 4.3 起在所有版本中都相同。请参阅 https://3v4l.org/X6lhm。如果你得到一个语法错误,你做错了什么。 (3认同)
  • 类型转换.是.输入Freakin CAST!好.+1 (3认同)
  • 还可以考虑使用`ArrayAccess`接口,也许与此解决方案结合使用.http://php.net/manual/en/class.arrayaccess.php (2认同)
  • @Howie 请参阅 [`empty` 的变更日志部分](http://php.net/manual/en/function.empty.php)。在 5.5 之前,您不能使用带有 `empty` 的表达式。这与类型转换完全无关;) (2认同)
  • 注意力!!!整数属性变得不可访问。虽然它们可以通过 print_r 等看到。 (2认同)
  • @Gordon 是的,没错。当有人从某个 API 接收对象时,这会带来混乱,该对象实际上应该是一个数组,对其进行解码和转换。最后看到数组元素但无法访问它们。 (2认同)
  • @Vishnja 好吧,你*可以*访问它们。就像我说的`$obj->{"0"}` 会起作用:) (2认同)

Jef*_*den 312

您可以依靠JSON编码/解码函数的行为快速将深层嵌套对象转换为关联数组:

$array = json_decode(json_encode($nested_object), true);
Run Code Online (Sandbox Code Playgroud)

  • 如果你想要一个完整的深度递归转换(当然不介意糟糕的性能),这是最好的解决方案 (10认同)
  • 恭敬地,我认为它仍然有用...不要忘记将第二个参数设置为true. (8认同)
  • @sics(, @celsowm):您可以通过在您的类中实现 JsonSerializable 来控制要导出的内容(也:如何):http://php.net/manual/en/class.jsonserializable.php (3认同)
  • 顺便说一句,这似乎在 php 5.5 上不再起作用,你将再次返回一个对象数组 (2认同)
  • 第二个参数解决了这个问题,适用于PHP 5.6.25.谢谢! (2认同)
  • 适用于嵌套对象!谢谢! (2认同)

Mau*_*ycy 62

从第一次谷歌搜索" php对象到关联数组 "我们有这个:

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;
}
Run Code Online (Sandbox Code Playgroud)

来自codesnippets.joyent.com.

  • 就个人而言,我不喜欢为每个值回忆功能的想法.我有一个类似的版本,但有3行:`function objectToArray($ o){$ a = array(); foreach($ o as $ k => $ v)$ a [$ k] =(is_array($ v)|| is_object($ v))?objectToArray($ v):$ v; 返回$ a; 这只是设置任何不是对象或数组的东西,并且除非必要,否则继续操作而不重复调用该方法. (14认同)
  • @ SpYk3HH:写下你自己的答案? (11认同)
  • “php 对象到关联数组”的第一个命中是 http://stackoverflow.com/questions/4345554/convert-php-object-to-associative-array (3认同)
  • @Ryan json 编码和解码不适用于浮点数的 NaN 和 INFINITE 值,并且可能存在其他我无法从我的头脑中想到的问题,但在许多情况下,它可能是一个更好的选择。至于优化,它需要的是上下文 - 让我插入我写的关于这个主题的帖子 https://www.evidentlycube.com/blog/game-optimization/when-to-optimize。总之,不要优化那些不会占用大量运行时间的东西,因为这些好处在整个应用程序的上下文中毫无意义。 (3认同)

Ram*_* K. 57

如果您的对象属性是公共的,您可以:

$array =  (array) $object;
Run Code Online (Sandbox Code Playgroud)

如果它们是私有的或受保护的,它们将在阵列上具有奇怪的键名.因此,在这种情况下,您将需要以下功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 私有和受保护变量的最佳解决方案! (3认同)

Isi*_*ius 14

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());
Run Code Online (Sandbox Code Playgroud)

产量

array(2) {
    ["b"]=>
    string(3) "two"
    ["Testc"]=>
    int(1)
}
array(1) {
    ["b"]=>
    string(3) "two"
}
Run Code Online (Sandbox Code Playgroud)


小智 12

这是一些代码:

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;
}
Run Code Online (Sandbox Code Playgroud)


Fra*_*ois 12

此处发布的所有其他答案仅适用于公共属性.这是一个使用反射和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;
}
Run Code Online (Sandbox Code Playgroud)

  • “为什么有人更喜欢数组而不是对象”我想编写一个方法,它使用 foreach 循环遍历对象属性的值,将它们写入 Excel 文件中。我希望这个方法独立于对象,这样我就可以将它与不同的数组一起使用。因此我的对象需要一个 _toArray() 方法 (2认同)

Joe*_*Joe 11

怎么样get_object_vars($obj)?如果您只想访问对象的公共属性,似乎很有用. http://www.php.net/function.get-object-vars


Ade*_*eel 10

键入将对象转换为数组.

$arr =  (array) $Obj;
Run Code Online (Sandbox Code Playgroud)

它会解决你的问题.

  • 这与接受的答案有何不同? (28认同)
  • 不,如果您具有私有或受保护的属性,则不会。 (4认同)
  • 最简单的解决方案。谢谢 (2认同)

小智 6

您可以轻松地使用此函数来获得结果:

function objetToArray($adminBar){
    $reflector = new ReflectionObject($adminBar);
    $nodes = $reflector->getProperties();
    $out = [];
    foreach ($nodes as $node) {
        $nod = $reflector->getProperty($node->getName());
        $nod->setAccessible(true);
        $out[$node->getName()] = $nod->getValue($adminBar);
    }
    return $out;
}
Run Code Online (Sandbox Code Playgroud)

使用PHP 5或更高版本。


小智 5

这是将PHP对象转换为关联数组的递归PHP函数:

// ---------------------------------------------------------
// ----- object_to_array_recursive --- function (PHP) ------
// ---------------------------------------------------------
// --- arg1: -- $object  =  PHP Object         - required --
// --- arg2: -- $assoc   =  TRUE or FALSE      - optional --
// --- arg3: -- $empty   =  '' (Empty String)  - optional --
// ---------------------------------------------------------
// ----- Return: Array from Object --- (associative) -------
// ---------------------------------------------------------

function object_to_array_recursive($object, $assoc=TRUE, $empty='')
{
    $res_arr = array();

    if (!empty($object)) {

        $arrObj = is_object($object) ? get_object_vars($object) : $object;

        $i=0;
        foreach ($arrObj as $key => $val) {
            $akey = ($assoc !== FALSE) ? $key : $i;
            if (is_array($val) || is_object($val)) {
                $res_arr[$akey] = (empty($val)) ? $empty : object_to_array_recursive($val);
            }
            else {
                $res_arr[$akey] = (empty($val)) ? $empty : (string)$val;
            }
            $i++;
        }
    }
    return $res_arr;
}

// ---------------------------------------------------------
// ---------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

用法示例:

// ---- Return associative array from object, ... use:
$new_arr1 = object_to_array_recursive($my_object);
// -- or --
// $new_arr1 = object_to_array_recursive($my_object, TRUE);
// -- or --
// $new_arr1 = object_to_array_recursive($my_object, 1);


// ---- Return numeric array from object, ... use:
$new_arr2 = object_to_array_recursive($my_object, FALSE);
Run Code Online (Sandbox Code Playgroud)

  • ..或oneliner:`$ new_arr1 =(array)$ my_object;` (3认同)

Bis*_*hoy 5

将 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个将 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用示例:

// 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);
Run Code Online (Sandbox Code Playgroud)


ovn*_*nia 5

用:

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;
}
Run Code Online (Sandbox Code Playgroud)

它返回一个没有特殊字符和类名的数组。


小智 5

要将对象转换为数组,只需显式转换它

$name_of_array = (array) $name_of_object;
Run Code Online (Sandbox Code Playgroud)


Joh*_*ith 5

首先,如果您需要对象中的数组,则可能应该首先将数据构造为数组。想一想。

不要使用foreach语句或JSON转换。如果您打算这样做,那么您将再次使用数据结构,而不是对象。

如果您确实需要它,请使用面向对象的方法来编写干净且可维护的代码。例如:

对象作为数组

class PersonArray implements \ArrayAccess, \IteratorAggregate
{
    public function __construct(Person $person) {
        $this->person = $person;
    }
    // ...
 }
Run Code Online (Sandbox Code Playgroud)

如果需要所有属性,请使用传输对象:

class PersonTransferObject
{
    private $person;

    public function __construct(Person $person) {
        $this->person = $person;
    }

    public function toArray() {
        return [
            // 'name' => $this->person->getName();
        ];
    }

 }
Run Code Online (Sandbox Code Playgroud)


Dan*_*ero 5

这个答案只是这篇文章的不同答案的联合,但它是将具有简单值或数组的公共或私有属性的 PHP 对象转换为关联数组的解决方案......

function object_to_array($obj)
{
    if (is_object($obj))
        $obj = (array)$this->dismount($obj);
    if (is_array($obj)) {
        $new = array();
        foreach ($obj as $key => $val) {
            $new[$key] = $this->object_to_array($val);
        }
    }
    else
        $new = $obj;
    return $new;
}

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;
}
Run Code Online (Sandbox Code Playgroud)


Bsi*_*enn 5

@SpYk3HH 的简短解决方案

function objectToArray($o)
{
    $a = array();
    foreach ($o as $k => $v)
        $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v;

    return $a;
}
Run Code Online (Sandbox Code Playgroud)


Rak*_*ati 5

您还可以在PHP中创建一个函数来转换对象数组:

function object_to_array($object) {
    return (array) $object;
}
Run Code Online (Sandbox Code Playgroud)