php 如何访问具有整数等名称的对象属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10333016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access object properties with names like integers?
提问by avinash shah
I am using json_decode()something like:
我正在使用json_decode()类似的东西:
$myVar = json_decode($data)
Which gives me output like this:
这给了我这样的输出:
[highlighting] => stdClass Object
(
[448364] => stdClass Object
(
[Data] => Array
(
[0] => Tax amount liability is .......
I want to access the string value in the key [0]. When I try to do something like:
我想访问键 [0] 中的字符串值。当我尝试执行以下操作时:
print $myVar->highlighting->448364->Data->0;
I get this error:
我收到此错误:
Parse error: syntax error, unexpected T_DNUMBER
解析错误:语法错误,意外的 T_DNUMBER
The two numerals/integers there seems to be problem.
那里的两个数字/整数似乎有问题。
回答by Jon
Updated for PHP 7.2
为 PHP 7.2 更新
PHP 7.2 introduced a behavioral change to converting numeric keys in object and array casts, which fixes this particular inconsistency and makes all the following examples behave as expected.
PHP 7.2 引入了对转换对象和数组强制转换中的数字键的行为更改,它修复了这种特殊的不一致性并使以下所有示例的行为都符合预期。
One less thing to be confused about!
少一件令人困惑的事情!
Original answer (applies to versions earlier than 7.2.0)
原始答案(适用于 7.2.0 之前的版本)
PHP has its share of dark alleys that you reallydon't want to find yourself inside. Object properties with names that are numbers is one of them...
PHP 有它的一部分黑暗的小巷,你真的不想发现自己在里面。名称为数字的对象属性就是其中之一......
What they never told you
他们从未告诉过你的事
Fact #1:You cannot access properties with names that are not legal variable names easily
事实 #1:您无法轻松访问名称不合法的变量名的属性
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->123foo; // error
Fact #2:You canaccess such properties with curly brace syntax
事实#2:您可以使用花括号语法访问此类属性
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'}; // OK!
Fact #3:But notif the property name is all digits!
事实 #3:但如果属性名称全是数字,则不然!
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
echo $o->{'123foo'}; // OK!
echo $o->{'123'}; // error!
Fact #4:Well, unless the object didn't come from an array in the first place.
事实#4:好吧,除非对象一开始就不是来自数组。
$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?
Pretty intuitive, don't you agree?
很直观,你不同意吗?
What you can do
你可以做什么
Option #1: do it manually
选项#1:手动执行
The most practical approach is simply to cast the object you are interested in back into an array, which will allow you to access the properties:
最实用的方法是简单地将您感兴趣的对象转换回数组,这将允许您访问属性:
$a = array('123' => '123', '123foo' => '123foo');
$o = (object)$a;
$a = (array)$o;
echo $o->{'123'}; // error!
echo $a['123']; // OK!
Unfortunately, this does not work recursively. So in your case you 'd need to do something like:
不幸的是,这不能递归地工作。因此,在您的情况下,您需要执行以下操作:
$highlighting = (array)$myVar->highlighting;
$data = (array)$highlighting['448364']->Data;
$value = $data['0']; // at last!
Option #2: the nuclear option
选项#2:核选项
An alternative approach would be to write a function that converts objects to arrays recursively:
另一种方法是编写一个函数,以递归方式将对象转换为数组:
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'];
However, I 'm not convinced that this is a better option across the board because it will needlessly cast to arrays all of the properties that you are notinterested in as well as those you are.
但是,我不相信这是一个更好的选择,因为它会不必要地将所有您不感兴趣的属性以及您感兴趣的属性强制转换为数组。
Option #3: playing it clever
选项#3:聪明地玩
An alternative of the previous option is to use the built-in JSON functions:
上一个选项的替代方法是使用内置的 JSON 函数:
$arr = json_decode(json_encode($myVar), true);
$value = $arr['highlighting']['448364']['Data']['0'];
The JSON functions helpfully perform a recursive conversion to array without the need to define any external functions. However desirable this looks, it has the "nuke" disadvantage of option #2 and additionallythe disadvantage that if there is any strings inside your object, those strings mustbe encoded in UTF-8 (this is a requirement of json_encode).
JSON 函数有助于执行到数组的递归转换,而无需定义任何外部函数。无论这看起来多么可取,它都有选项 #2 的“核弹”缺点,另外还有一个缺点,即如果您的对象中有任何字符串,则这些字符串必须以 UTF-8 编码(这是 的要求json_encode)。
回答by Pebbl
Just wanted to add to Jon's eloquent explanation the reason why this fails. It's all because when creating an array, php converts keys to integers — if it can — which causes lookup problems on arrays which have been cast to objects, simply because the numeric key is preserved. This is problematic because all property access options expect or convert to strings. You can confirm this by doing the following:
只是想在 Jon 雄辩的解释中添加失败的原因。这都是因为在创建数组时,php 将键转换为整数(如果可以的话),这会导致在已转换为对象的数组上出现查找问题,仅仅是因为保留了数字键。这是有问题的,因为所有属性访问选项都期望或转换为字符串。您可以通过执行以下操作来确认这一点:
$arr = array('123' => 'abc');
$obj = (object) $arr;
$obj->{'123'} = 'abc';
print_r( $obj );
Which would output:
这将输出:
stdClass Object (
[123] => 'abc',
[123] => 'abc'
)
So the object has two property keys, one numeric (which can't be accessed) and one string based. This is the reason why Jon's #Fact 4works, because by setting the property using curly braces means you always define a string-based key, rather than numeric.
因此该对象有两个属性键,一个数字(无法访问)和一个基于字符串的键。这就是 Jon#Fact 4工作的原因,因为通过使用花括号设置属性意味着您始终定义基于字符串的键,而不是数字。
Taking Jon's solution, but turning it on its head, you can generate an object from your array that always has string-based keys by doing the following:
采用 Jon 的解决方案,但反过来,您可以通过执行以下操作,从始终具有基于字符串的键的数组中生成一个对象:
$obj = json_decode(json_encode($arr));
From now on you can use either of the following because access in this manner always converts the value inside the curly brace to a string:
从现在开始,您可以使用以下任一方法,因为以这种方式访问总是将花括号内的值转换为字符串:
$obj->{123};
$obj->{'123'};
Good old illogical PHP...
好老的不合逻辑的 PHP ......
回答by Zydnar
If an object begins with @like:
如果对象以@like开头:
SimpleXMLElement Object (
[@attributes] => Array (
[href] => qwertyuiop.html
[id] => html21
[media-type] => application/xhtml+xml
)
)
You have to use:
你必须使用:
print_r($parent_object->attributes());
because $parent_object->{'@attributes'}or $parent_object['@attributes']won't work.
因为$parent_object->{'@attributes'}或$parent_object['@attributes']不会工作。
回答by Bluekable
A final alternative to Jon's comprehensive answer:
乔恩综合答案的最终替代方案:
Simply use json_decode() with the second parameter set to true.
只需使用 json_decode() 并将第二个参数设置为true。
$array = json_decode($url, true);
This then returns an associative array rather than an object so no need to convert after the fact.
然后这将返回一个关联数组而不是一个对象,因此无需事后转换。
This may not be suitable to every application but it really helped me to easily reference a property of the oroginal object.
这可能不适用于每个应用程序,但它确实帮助我轻松引用原始对象的属性。
Solution was found in this tutorial - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/
在本教程中找到了解决方案 - http://nitschinger.at/Handling-JSON-like-a-boss-in-PHP/
Regards
问候
回答by umesh kadam
For PHP 7
对于 PHP 7
Accessing Object properties having numbers as property name. Mostly needed after casting array to object.
访问以数字作为属性名称的对象属性。在将数组转换为对象后最需要。
$arr = [2,3,7];
$o = (object) $arr;
$t = "1";
$t2 = 1;
$t3 = (1);
echo $o->{1}; // 3
echo $o->{'1'}; // 3
echo $o->$t; // 3
echo $o->$t2; // 3
echo $o->$t3; // 3
echo $o->1; // error
echo $o->(1); // error
回答by Ruwantha
I had copied this function from the net. If it works as it says ("Function to Convert stdClass Objects to Multidimensional Arrays"), try the following:
我从网上复制了这个功能。如果它如它所说的那样工作(“将 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;
}
}
?>
- first pass your array to
objectToArrayfunction - then take the return value
- echo
[highlighting][448364][Data][0]
- 首先将您的数组传递给
objectToArray函数 - 然后取返回值
- 回声
[highlighting][448364][Data][0]
回答by Gustav
I'm afraid you aren't allowed to name objects starting with numerics. Rename the first one "448364" starting with a letter.
恐怕你不能命名以数字开头的对象。重命名第一个以字母开头的“448364”。
The second one is an array, those are to be accessed by brackets like so:
第二个是一个数组,它们将通过括号访问,如下所示:
print myVar->highlighting->test_448364->Data[0]
instead
反而

