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

如何访问一个PHP关联数组元素,其输出是:

[highlighting] => stdClass Object ( [448364] => stdClass Object ( [Data] => Array ( [0] => Tax amount liability is ....... 

我想访问键[0]中的string值。 我想做一些事情:

 print myVar->highlighting->448364->Data->0 

但是这两个数字/整数似乎有问题。

编辑:

我会在这里给我一些历史从哪里得到myVar。 我正在使用json_decode()类似于:

 $myVar = json_decode(url) 

PHP有一些黑暗的小巷,你真的不想在里面find自己。 名称为数字的对象属性就是其中之一…

他们从来没有告诉过你

事实#1:您不能轻易访问名称不是合法variables名称的属性

 $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:那么,除非对象不是来自arrays的第一位。

 $a = array('123' => '123'); $o1 = (object)$a; $o2 = new stdClass; $o2->{'123'} = '123'; // setting property is OK echo $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! 

不幸的是,这不能recursion地工作。 所以在你的情况下,你需要做一些事情:

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

选项2:核选项

另一种方法是编写一个将对象recursion转换为数组的函数:

 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']; 

不过,我不相信这是一个更好的select,因为它将不必要地投射到你感兴趣的所有属性以及你自己。

选项#3:聪明地玩

上一个选项的另一种select是使用内置的JSON函数:

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

JSON函数有助于执行向数组的recursion转换,而无需定义任何外部函数。 然而,看起来这样看来,它具有选项#2的“nuke”缺点, 另外缺点是如果对象内有任何string,则这些string必须以UTF-8编码(这是json_encode的要求)。

只是想增加Jon的雄辩的解释,为什么这个失败。 这完全是因为当创build一个数组时,php会将键转换为整数(如果可以的话),这会导致数组中已经被转换为对象的查找问题,只是因为数字键被保留。 这是有问题的,因为所有的财产访问选项期望或转换为string。 您可以通过执行以下操作来确认这一点:

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

哪个会输出:

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

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

以Jon的解决scheme,但把它的头,你可以从您的arrays总是有基于string的键生成一个对象通过执行以下操作:

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

从现在开始,您可以使用以下两种方法之一,因为以这种方式访问​​总是将大括号内的值转换为string:

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

好老的不合逻辑的PHP …

我从网上复制了这个function。 如果它的工作原理(“将stdClass对象转换为multidimensional array的函数”),请尝试以下操作:

 <?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数组和数组stdClass

Jon的综合答案的最后一个select:

只需使用第二个参数设置为true的 json_decode()。

 $array = json_decode($url, true); 

这然后返回一个关联数组而不是一个对象,所以不需要在事实之后进行转换。

这可能不适合每一个应用程序,但它确实帮助我轻松地引用了原始对象的属性。

解决scheme在本教程中find – http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/

问候

恐怕你不能命名以数字开头的对象。 重命名以字母开头的第一个“448364”。

第二个是一个数组,那些括号可以像这样访问:

 print myVar->highlighting->test_448364->Data[0] 

代替

如果一个对象以@开始,如:

 SimpleXMLElement Object ( [@attributes] => Array ( [href] => qwertyuiop.html [id] => html21 [media-type] => application/xhtml+xml ) ) 

你必须使用:

 print_r($parent_object->attributes()); 

因为$parent_object->{'@attributes'}$parent_object['@attributes']将不起作用。