给出一个包含该字符串的变量:
$property = 'parent->requestdata->inputs->firstname';
还有一个对象:
$obj->parent->requestdata->inputs->firstname = 'Travis';
如何使用字符串访问值“ Travis”?我尝试过:
$obj->{$property}
但它会查找名为“ parent-> requestdata-> inputs-> firstname”的属性,而不是位于$ obj-> parent-> requestdtaa-> inputs-> firstname`的属性
我尝试了各种类型的串联,使用var_export()以及其他方法。我可以将其分解为数组,然后像在this question中那样循环数组。
但是变量'$ property'可以容纳16个深度的值。而且,我正在解析的数据可以具有数百个我需要导入的属性,因此,在每次迭代之前循环遍历并返回值,直到达到16 X 100级为止似乎效率很低。尤其是考虑到我一开始就知道该属性的实际位置。
在给定'Travis'
和(stdClass)$obj
的情况下,如何获得值(string)$property
?
答案 0 :(得分:0)
您是正确的,您必须为每个嵌套对象进行循环迭代,但是您不必为每个嵌套对象循环“数百个属性”,您只需访问要查找的对象即可用于:
$obj = new SomeObject;
$property = 'parent->requestdata->inputs->firstname';
$props = explode("->", $property);
while ($props) {
$prop = array_shift($props);
$obj = $obj->$prop ?? null;
}
完全未经测试,但似乎应该可以正常运行。就是说,这听起来像是an X-Y problem。
答案 1 :(得分:0)
我的最初搜索没有产生很多结果,但是,在考虑了更广泛的搜索词之后,我在SO上发现了其他类似问题的问题。我提出了三种解决方案。所有人都会工作,但并非所有人都能工作。
解决方案1-循环播放
使用与原始问题中引用的问题类似的方法或@ miken32提出的循环将起作用。
解决方案2-匿名功能
该字符串可以分解为数组。然后可以使用array_reduce()解析该数组以产生结果。就我而言,工作代码(检查不正确/不存在的属性名称/拼写)是(PHP 7 +):
//create object - this comes from and external API in my case, but I'll include it here
//so that others can copy and paste for testing purposes
$obj = (object)[
'parent' => (object)[
'requestdata' => (object)[
'inputs' => (object)[
'firstname' => 'Travis'
]
]
]
];
//string representing the property we want to get on the object
$property = 'parent->requestdata->inputs->firstname';
$name = array_reduce(explode('->', $property), function ($previous, $current) {
return is_numeric($current) ? ($previous[$current] ?? null) : ($previous->$current ?? null); }, $obj);
var_dump($name); //outputs Travis
有关潜在的相关信息和我基于其答案的代码,请参见this question。
解决方案3-symfony属性访问组件
就我而言,使用作曲家很容易需要此组件。它允许使用简单的字符串访问数组和对象的属性。您可以在symfony网站上read about how to use it。对我来说,与其他选项相比,它的主要好处是错误检查。
我的代码最终看起来像这样:
//create object - this comes from and external API in my case, but I'll include it here
//so that others can copy and paste for testing purposes
//don't forget to include the component at the top of your class
//'use Symfony\Component\PropertyAccess\PropertyAccess;'
$obj = (object)[
'parent' => (object)[
'requestdata' => (object)[
'inputs' => (object)[
'firstname' => 'Travis'
]
]
]
];
//string representing the property we want to get on the object
//NOTE: syfony uses dot notation. I could not get standard '->' object notation to work.
$property = 'parent.requestdata.inputs.firstname';
//create symfony property access factory
$propertyAccessor = PropertyAccess::createPropertyAccessor();
//get the desired value
$name = $propertyAccessor->getValue($obj, $property);
var_dump($name); //outputs 'Travis'
所有三个选项都将起作用。选择最适合您的一款。