将 PHP 对象转换为关联数组

问:

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

我想要一个快速而简单的函数来将对象转换为数组。

答1:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

只是打字

$array = (array) $yourObject;

来自 Arrays:

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

示例:简单对象

$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 );

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

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(
  )),
)

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

另请参阅这篇深入的博客文章:

快速 PHP 对象到数组的转换

还要考虑 ArrayAccess 接口,可能与此解决方案结合使用。 php.net/manual/en/class.arrayaccess.php

如果您有整数键,则将转换为字符串,这可能会导致大问题。例如 [1 => "one"] 变成 ["1" => "one"]

@Howie 使用 (array) 和 (object) 进行类型转换在 PHP 4.3 之后的所有版本中都可靠且相同。请参阅3v4l.org/X6lhm。如果你得到一个语法错误,你做错了什么。

@Howie 看到 Changelog section for empty。在 5.5 之前,您不能使用带有 empty 的表达式。这与类型转换完全无关;)

类型转换。是的。类型 Freakin CAST!好的。 +1

答2:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

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

$array = json_decode(json_encode($nested_object), true);

如果您想要全深度递归转换(当然不介意性能不佳),这是最好的解决方案

顺便说一句,这似乎不再适用于 php 5.5,您将再次获得一组对象

尊敬的,我认为它仍然有效......不要忘记将第二个参数设置为true。

第二个参数解决了这个问题,适用于 PHP 5.6.25。谢谢!

@sics(, @celsowm):您可以通过在您的类中实现 JsonSerializable 来控制要导出的内容(也:如何):php.net/manual/en/class.jsonserializable.php

答3:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

从谷歌第一次命中“PHP 对象到关联数组”,我们有这样的:

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;
}

源是 at codesnippets.joyent.com。

将其与 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

就个人而言,我不喜欢为每个值调用函数的想法。我有一个类似的版本,但只有 3 行: function objectToArray($o) { $a = array(); foreach ($o as $k => $v) $a[$k] = (is_array($v) || is_object($v)) ? objectToArray($v): $v; return $a; } 这只是设置任何不是对象或数组的东西,并且除非必要,否则不会重复调用该方法。

@SpYk3HH:写你自己的答案?

“php object to assoc array”的第一个命中是 stackoverflow.com/questions/4345554/…

这(以及来自@SpYk3HH 的版本)对我来说似乎比 json_encode 选项(stackoverflow.com/a/16111687/470749)执行得更慢。我不知道为什么这些方法会更可取。

@Ryan json 编码和解码不适用于浮点的 NaN 和 INFINITE 值,并且可能存在我无法想到的其他问题,但在许多情况下,它可能是更好的选择。至于优化,它需要的是上下文 - 让我插入我在这个主题 evidentlycube.com/blog/game-optimization/when-to-optimize 上写的一篇文章。 tl;博士是,不要优化不占用大量运行时间的东西,因为这些好处在整个应用程序的上下文中毫无意义。

答4:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

如果您的对象属性是公开的,您可以执行以下操作:

$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;
}

如果您的财产受到保护,setAccessible(false) 会将其改回受保护的可见性吗?还是会将其设为私有?

我发现的唯一解决方案适用于受保护的属性。谢谢

私有和受保护变量的最佳解决方案!!

这里的行 $property->setAccessible(false);将在每个财产上执行 - 即使它是公开的......

我想另一种方法是将其转换为数组,然后从私有属性中去除文本前缀。不那么危险,因为您的方法有将公共属性设置为私有的风险

答5:

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

get_object_vars($obj) 呢?如果您只想访问对象的公共属性,这似乎很有用。

请参阅 get_object_vars。

答6:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

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"
}

这个解决方案的优缺点?声明为 class Test { const A = 1; 的类呢?公共 $parent = new Test(); }

答7:

huntsbot.com – 高效赚钱,自由工作

类型将您的对象转换为数组。

$arr =  (array) $Obj;

它会解决你的问题。

不,如果您有私有或受保护的财产,它不会。

最简单的解决方案。谢谢

答8:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

这是一些代码:

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;
}

最适合我(但我需要删除“xxx”并返回 $data)

答9:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

此处发布的所有其他答案仅适用于公共属性。这是一种使用反射和 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;
}

是的,但是...如果您使用 Object/Array 作为变量,这也是所有这些导致的,为什么除了 public 属性之外还需要其他属性?

@SpYk3HH:我没有问这个问题。我什至不知道为什么有人会更喜欢数组而不是对象。

嗯,我经常更喜欢将查询结果转换为数组,只是为了提供一个统一的“列表”用于循环,因为应用程序中必须“循环”的大多数其他东西往往是数组。只是让编写“通用循环方法”变得容易。通常,如果我正在使用一个对象,我不会遍历它的属性,而是将它用作对象并根据需要使用这些属性。

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

答10:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

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

$name_of_array = (array) $name_of_object;

答11:

打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

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

function object_to_array($object) {
    
    
    return (array) $object;
}

原文链接:https://www.huntsbot.com/qa/PAl0/convert-a-php-object-to-an-associative-array?lang=zh_CN&from=csdn

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

猜你喜欢

转载自blog.csdn.net/kalman2019/article/details/128732227