为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用整数等名称访问对象属性?

如何使用整数等名称访问对象属性?

PHP
慕虎7371278 2019-06-14 16:33:36
如何使用整数等名称访问对象属性?如何访问输出为:[highlighting] => stdClass Object         (             [448364] => stdClass Object                 (                     [Data] => Array                         (                             [0] => Tax amount liability is .......我想访问键[0]中的字符串值。我想做这样的事情:print myVar->highlighting->448364->Data->0但这两个数字/整数似乎有问题。编辑:我将在这里介绍一些历史,我从哪里得到我的瓦尔。我在用json_decode()类似于:$myVar = json_decode(url)
查看完整描述

3 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

更新PHP 7.2

PHP7.2引入了对在对象和数组转换中转换数字键,它修复了这种特殊的不一致性,并使以下所有示例都按照预期的方式运行。

少了一件让人困惑的事!


原始答案(适用于7.2.0之前的版本)

PHP有它那部分黑暗的小巷真的不想发现自己在里面。具有数字名称的对象属性就是其中之一.

他们从没告诉过你

事实1:您不能很容易地使用非合法变量名称的名称访问属性。

$a = array('123' => '123', '123foo' => '123foo');$o = (object)$a;echo $o->123foo; // error

事实2:你,你们能,会,可以使用大括号语法访问此类属性

$a = array('123' => '123', '123foo' => '123foo');$o = (object)$a;echo $o->{'123foo'}; // OK!

事实3:如果属性名为所有数字!

$a = array('123' => '123', '123foo' => '123foo');$o = (object)$a;echo $o->{'123foo'}; // OK!echo $o->{'123'}; // error!

活例.

事实4:嗯,除非对象一开始不是来自数组。

$a = array('123' => '123');$o1 = (object)$a;$o2 = new stdClass;$o2->{'123'} = '123'; // setting property is OKecho $o1->{'123'}; 
// error!echo $o2->{'123'}; // works... WTF?

活例.

很直观,你不同意吗?

你能做什么

选项1:手动执行

最实际的方法是将您感兴趣的对象转换回数组中,这将允许您访问属性:

$a = array('123' => '123', '123foo' => '123foo');$o = (object)$a;$a = (array)$o;echo $o->{'123'}; // error!echo $a['123']; // OK!

不幸的是,这不能递归地工作。因此,在你的情况下,你需要做如下的事情:

$highlighting = (array)$myVar->highlighting;$data = (array)$highlighting['448364']->Data;$value = $data['0']; // at last!

备选案文2:核选择

另一种方法是编写一个函数,递归地将对象转换为数组:

function recursive_cast_to_array($o) {
    $a = (array)$o;
    foreach ($a as &$value) {
        if (is_object($value)) {
            $value = recursive_cast_to_array($value);
        }
    }

    return $a;}$arr = recursive_cast_to_array($myVar);$value = $arr['highlighting']['448364']['Data']['0'];

但是,我并不认为这是一个更好的选择,因为它将不必要地将数组转换为您所拥有的所有属性。对你感兴趣的人也一样。

选项3:聪明地玩它

前面选项的另一种选择是使用内置的JSON函数:

$arr = json_decode(json_encode($myVar), true);$value = $arr['highlighting']['448364']['Data']['0'];

JSON函数有助于执行对数组的递归转换,而无需定义任何外部函数。不管这看起来有多好,它都有选项2的“核子”的缺点。另外缺点是,如果对象中有任何字符串,则这些字符串在UTF-8中编码(这是json_encode).


查看完整回答
反对 回复 2019-06-14
?
互换的青春

TA贡献1797条经验 获得超6个赞

只是想补充一下乔恩雄辩的解释,这是为什么失败的原因。这都是因为在创建数组时,php会将键转换为整数(如果可以的话),这会导致对已转换为对象的数组的查找问题,这仅仅是因为保留了数字键。这是有问题的,因为所有属性访问选项都期望或转换为字符串。您可以通过执行以下操作来确认这一点:

$arr = array('123' => 'abc');$obj = (object) $arr;$obj->{'123'} = 'abc';print_r( $obj );

它的产出:

stdClass Object ( 
  [123] => 'abc', 
  [123] => 'abc')

因此,对象有两个属性键,一个数字(不能访问)和一个基于字符串的键。这就是为什么乔恩#Fact 4工作,因为通过使用大括号设置属性,意味着您总是定义一个基于字符串的键,而不是数字。

采用Jon的解决方案,但将其翻转,您可以通过执行以下操作从数组中生成一个对象,该对象始终具有基于字符串的键:

$obj = json_decode(json_encode($arr));

从现在开始,您可以使用以下任一项,因为Access总是以这种方式将大括号内的值转换为字符串:

$obj->{123};$obj->{'123'};

好旧的不合逻辑的PHP.。


查看完整回答
反对 回复 2019-06-14
?
紫衣仙女

TA贡献1839条经验 获得超15个赞

我从网上复制了这个功能。如果它按其规定工作(“函数将stdClass对象转换为多维数组”),请尝试以下操作:

<?php    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;
        }
    }?>
  • 首先将数组传递给

    objectToArray

    功能
  • 然后取返回值
  • 回波

    [highlighting][448364][Data][0]

资料来源:PHP stdClass to Array,Array to stdClass


查看完整回答
反对 回复 2019-06-14
  • 3 回答
  • 0 关注
  • 461 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信