Dynamic access to a nested object

I am creating a geocoding class that can use several web services for geocoding (e.g. Google, Yahoo, Bing, etc.). I am trying to do this so that new web services can be easily configured. Most web services return either XML / JSON .. for PHP. I chose XML as my primary focus. All the code is already in place, but now Google, for example, returns the following XML (converted to simple_xml_element)

SimpleXMLElement Object
 (
[status] => OK
[result] => Array
    (
        [0] => SimpleXMLElement Object
            (
                [type] => postal_code
                [formatted_address] => 1010 Lausanne, Switzerland
                [address_component] => Array
                    (
                        [0] => SimpleXMLElement Object
                            (
                                [long_name] => 1010
                                [short_name] => 1010
                                [type] => postal_code
                            )

                        [1] => SimpleXMLElement Object
                            (
                                [long_name] => Lausanne
                                [short_name] => Lausanne
                                [type] => Array
                                    (
                                        [0] => locality
                                        [1] => political
                                    )

                            )

                        [2] => SimpleXMLElement Object
                            (
                                [long_name] => Vaud
                                [short_name] => VD
                                [type] => Array
                                    (
                                        [0] => administrative_area_level_1
                                        [1] => political
                                    )

                            )

                        [3] => SimpleXMLElement Object
                            (
                                [long_name] => Switzerland
                                [short_name] => CH
                                [type] => Array
                                    (
                                        [0] => country
                                        [1] => political
                                    )

                            )

                    )

                [geometry] => SimpleXMLElement Object
                    (
                        [location] => SimpleXMLElement Object
                            (
                                [lat] => 46.5376186
                                [lng] => 6.6539665
                            )

                        [location_type] => APPROXIMATE
                        [viewport] => SimpleXMLElement Object
                            (
                                [southwest] => SimpleXMLElement Object
                                    (
                                        [lat] => 46.5253574
                                        [lng] => 6.6384420
                                    )

                                [northeast] => SimpleXMLElement Object
                                    (
                                        [lat] => 46.5467887
                                        [lng] => 6.6745222
                                    )

                            )

                        [bounds] => SimpleXMLElement Object
                            (
                                [southwest] => SimpleXMLElement Object
                                    (
                                        [lat] => 46.5253574
                                        [lng] => 6.6384420
                                    )

                                [northeast] => SimpleXMLElement Object
                                    (
                                        [lat] => 46.5467887
                                        [lng] => 6.6745222
                                    )

                            )

                    )

            )
)

I need the information in the [location] tag, so I tried to save the path in var:

$lat_path = 'result[0]->geometry->location->lat;

And then try to access the value this way:

(suppose $xml is the object)
$xml->{$lat_path};

But that does not work. Is there a way to access information dynamically or based on variables. I don’t want to ruin my geocoding method with specific Google code.

!

+5
3

$xml->{$lat_path};

PHP - $lat_path . T_OBJECT_OPERATOR.

 'result[0]->geometry->location->lat;'

$xml. :

$obj = new StdClass;
$obj->{'result[0]->geometry->location->lat;'} = 1;
print_r($obj);

stdClass Object
(
    [result[0]->geometry->location->lat;] => 1
)

, , .

, XPath :

$xml->result[0]->geometry->location->lat;
+2

xPath , :

$oObj = new StdClass;
$oObj->Root->Parent->ID = 1;
$oObj->Root->Parent->Child->ID = 2;

$sSeachInTree = 'Root\\Parent\\Child\\ID';
$aElements = explode("\\",$sSeachInTree);

foreach($aElements as $sElement)
{
    if (isset($oObj->{$sElement}))
    {
        if (end($aElements) == $sElement)       
        {
            echo "Found: " . $sElement . " = " . $oObj->{$sElement};
        }
        $oObj = $oObj->{$sElement};
    }
}
+1

. .

<?php
  /**
 * Traverse an object by splitting the path in the argument
 * Only returns values that are in nested objects not arrays
 */
function get_property_from_nested_objects(object $object, string $path, $default_fallback = null)
{
    if (strpos($path, '->') !== false) {
        $path_properties = explode('->', $path);
    } else {
        return isset($object->$path) ? $object->$path : $default_fallback;
    }

    $nested_objects = [];

    foreach ($path_properties as $nested_obj_index => $object_key) {
        if (isset($object->$object_key) && is_object($object->$object_key)) {
            $nested_objects[$nested_obj_index] = $object->$object_key;
            continue;
        } elseif (isset($nested_objects[$nested_obj_index - 1]->$object_key) && is_object($nested_objects[$nested_obj_index - 1]->$object_key)) {
            $nested_objects[$nested_obj_index] = $nested_objects[$nested_obj_index - 1]->$object_key;
            continue;
        } elseif (isset($nested_objects[$nested_obj_index - 1]->$object_key) && !is_object($nested_objects[$nested_obj_index - 1]->$object_key)) {
            return $nested_objects[$nested_obj_index - 1]->$object_key;
        } else {
            return $default_fallback;
        }
    }
}

echo get_property_from_nested_objects((object)[
    'obj1' => (object) [
        'prop' => 'works'
    ] 
], 'obj1->prop');

// output: 'works'
0
source

All Articles