我从查询中获得了一个结果集,该结果为我提供了一个具有数十个字段的对象,下面的示例是一个子集:
[79] => stdClass Object
(
[name] => John Doe
[email] => john@doe.com
[ext] => 4004
[options] => stdClass Object
(
[type] => friend
[rating] => Excellent
[context] => default
)
[address] => 123 Anywhere St
)
我不想只遍历每个字段,因为我只想要其中的几个,而是尝试使用数组来获取我想要的内容:
$fields = array('name','email','options->type','options->rating','address');
然后我这样做:
foreach ($result as $k => $v){
foreach ($fields as $kk => $vv){
echo $kk. " - " . $v->$kk."<br>";
}
}
这给了我字段名称及其值。
name - John Doe
email - john@doe.com
address - 123 Anywhere St.
但是,sub object(options)
中的任何内容给我一个空白的结果。
答案 0 :(得分:2)
您可以使用递归函数,前提是您不介意将$fields
var的格式更改为包括数组。在我看来,这使得它更容易阅读,也更容易在代码中处理。
使用递归函数的好处是它将处理任何深度。
$o = (object) [
'name' => 'John Doe',
'email' => 'john@doe.com',
'ext' => 4004,
'options' => (object) [
'type' => 'friend',
'rating' => 'Excellent',
'context' => 'default',
'any' => (object) [
'depth' => (object) [
'will' => 'work'
]
]
],
'address' => '123 Anywhere St'
];
$fields = [
'name',
'email',
'options' => [
'type',
'rating',
'any' => [
'depth' => [
'will'
]
]
],
'address'
];
function getObjectProps($o, $fields, $parent = '') {
if (strlen($parent)) {
$parent .= '->';
}
foreach ($fields as $k => $v) {
if (is_array($v)) {
getObjectProps($o->{$k}, $v, $parent . $k);
} else {
echo $parent . $v . ' - ' . $o->{$v} . '<br/>';
}
}
}
getObjectProps($o, $fields);
输出:
name - John Doe
email - john@doe.com
options->type - friend
options->rating - Excellent
options->any->depth->will - work
address - 123 Anywhere St
答案 1 :(得分:0)
为$fields
使用多维数组,并稍微更改您的foreach循环:
$fields = [
'name',
'email',
'options' => [
'type',
'rating'
],
'address'
];
foreach ($result as $obj) {
foreach ($fields as $k => $v) {
if (is_array($v)) {
foreach ($v as $vv) {
echo $vv . ' - ' . $obj->$k->$vv . '<br>';
}
} else {
echo $v . ' - ' . $obj->$v . '<br>';
}
}
}
答案 2 :(得分:0)
这是我在此期间想到的
$someObject = new stdClass();
$someObject->name = 'Dale';
$someObject->options = new stdClass();
$someObject->options->address = 'The Address';
$fields = ['name', 'options' => ['address']];
function toArray($object, $fields) {
$return = [];
foreach($fields as $fieldKey => $fieldValue) {
if(!is_array($fieldValue)) {
$return [] = $object->$fieldValue;
}
else
{
$return = array_merge($return, toArray($object->$fieldKey, $fieldValue));
}
}
return $return;
}
print_r(toArray($someObject, $fields));
答案 3 :(得分:0)
尝试以下代码:
$newResult = array_intersect_key((array)$result, array_flip($fields));
答案 4 :(得分:0)
没有像您尝试的那样简单的方法来访问属性。但是有一个symfony's property access component可以使用。但是,如果您专注于使用自己的方法,那么您可能会喜欢以下代码。我在PHP 7.2中运行了这段代码
$data = (object) [
'name' => 'John Doe',
'email' => 'john@doe.com',
'ext' => 4004,
'options' => (object) [
'type' => "friend",
'rating' => 'Excellent',
'context' => 'default'
],
'address' => '123 Anywhere St'
];
$fields = array('name','email','options->type','options->rating','address');
/*** way of initializing
$response = []; // get array value here
$response = ""; // get string value here
***/
$response = ""; //string value here... as output
/*** Don't you think that the below code now is clean and reusable? ***/
array_map(function($key) use($data, &$response) {
$value = array_reduce(explode('->', $key), function ($o, $p) {
return $o->$p;
}, $data);
is_array($response) ? ($response[$key] = $value) : ($response .= $key . ' - ' . $value . '<br>');
}, $fields);
echo $response;
在上面的代码中,如果将$response
初始化为空数组,则将得到数组作为输出。如果将其初始化为空字符串,则将获得字符串输出。而且我认为与其使用for loop
和array_map
而不是使用array_reduce
,它们像魔术一样工作,也减少了您的代码。
字符串作为输出:
输出数组: