我正在构建一个Geocoding类,可以利用多个Web服务进行地理编码(即Google,Yahoo,Bing等)。我试图以一种可以轻松配置新的Web服务的方式来实现它。大多数web服务返回XML / JSON ..对于PHP我选择XML作为我的主要焦点。所有代码都已到位,但现在Google会返回以下XML(转换为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
)
)
)
)
)
我需要的信息在[location]标签中,所以我尝试将路径存储在var中:
$lat_path = 'result[0]->geometry->location->lat;
然后尝试以这种方式访问该值:
(suppose $xml is the object)
$xml->{$lat_path};
但这不起作用。有什么方法可以动态或基于变量访问信息。我不想破坏使用Google特定代码的地理编码方法。
谢谢!
答案 0 :(得分:2)
当你这样做时
$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;
答案 1 :(得分:1)
如果您无法使用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};
}
}
答案 2 :(得分:0)
我今天遇到了这个问题。这是我的解决方案。
<?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'