PHP从字段名称数组中获取对象数据

时间:2018-07-17 10:30:23

标签: php arrays object

我从查询中获得了一个结果集,该结果为我提供了一个具有数十个字段的对象,下面的示例是一个子集:

[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)中的任何内容给我一个空白的结果。

5 个答案:

答案 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 looparray_map而不是使用array_reduce,它们像魔术一样工作,也减少了您的代码。

字符串作为输出:

String as output

输出数组:

Array as output