我正在尝试获取远程XML文件的一部分,在本例中,通过Google Maps获取邮政编码的经度和纬度。这是我目前正在使用的函数:
function slug_get_coordinates( $zip ) {
$url = "http://maps.googleapis.com/maps/api/geocode/xml?address={$zip}&sensor=false";
$result = simplexml_load_file( $url );
$coordinates = $result->result->geometry->location;
return $coordinates;
}
这有时会在长时间页面加载后起作用,但通常会超时。有没有一种方法可以直接到达我需要的XML文件部分,而不需要加载整个文件,或者其他一些优化方法?
发布于 2014-07-12 02:58:23
除非服务提供此功能,否则您不能基于选择器(例如XPath / CSS)请求部分响应。
关于效率,我建议尽可能详细地分解请求时间,以找出为什么某个请求需要一段时间。cURL对此有很好的支持,例如:
$zip = urlencode('1 infinite loop');
$ch = curl_init("http://maps.googleapis.com/maps/api/geocode/xml?address={$zip}&sensor=false");
curl_exec($ch);
print_r(curl_getinfo($ch));
这将产生一个包含请求的所有元数据的数组:
Array
(
...
[total_time] => 0.11955
[namelookup_time] => 0.02996
[connect_time] => 0.035803
[pretransfer_time] => 0.035874
...
[size_upload] => 0
[size_download] => 1737
[speed_download] => 14529
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => 0
[starttransfer_time] => 0.119444
[redirect_time] => 0
...
)
有了这些数据,您就可以制定适当的方法来处理这个问题。缓存响应可能会减少经常重复搜索的请求时间,但它可能不适用于您的特定情况。
发布于 2014-07-12 09:14:25
通过
获取远程XML文件的一部分最有效的方法是什么?
这个问题不能具体回答,因为这有很多影响。
实际上,您在这里处理的是一个远程服务。我通常建议总是包装/代理这些(比较:)。这是因为它们总是带有许多含义。通过将数据检索封装到一个函数中,您已经部分地做到了这一点:
function slug_get_coordinates( $zip ) {
$url = "http://maps.googleapis.com/maps/api/geocode/xml?address={$zip}&sensor=false";
$result = simplexml_load_file( $url );
$coordinates = $result->result->geometry->location;
return $coordinates;
}
然而,这个单一的功能不足以处理这样的服务可能带来的所有问题。例如,远程位置可能只是关闭了-这样的响应超时可能是合格的-或者正如你所经历的那样,它只是花费了太长的时间。
所以你基本上对服务的质量不满意。
由于远程服务通常不能完全控制它们,并且对服务质量的影响很小,因此包装它的好处是可以在包装器中处理此类问题,从而保护应用程序逻辑的其余部分不受所有这些影响的影响。
您还需要有错误处理,这是您的函数中所缺少的。这里的另一个提示是为失败而设计。例如,让您的应用程序仍然工作,甚至您试图检索(添加)的信息丢失。
这样的代理的另一个好处是,您可以在其中实现调试功能。例如,使用您提供的代码,我完全可以快速检索数据:
$zip = '55416';
$start = microtime(true);
slug_get_coordinates($zip)->asXML('php://output');
printf("\n----\nTook %.5f seconds\n", microtime(true) - $start);
输出:
<location>
<lat>44.9465193</lat>
<lng>-93.3439291</lng>
</location>
----
Took 0.11873 seconds
如果需要更深入地研究远程请求,可以挂钩PHP的流通知。我已经编译了一个,它可以完成这方面的工作,并且可以很容易地注册:
$zip = '55416';
$notifier = new StreamNotifyPrinter();
libxml_set_streams_context($notifier->registerOnContext());
$start = microtime(true);
slug_get_coordinates($zip)->asXML('php://output');
printf("\n----\nTook %.5f seconds\n", microtime(true) - $start);
输出:
2014-07-12T09:07:40.146422+0000 [0.00000] Connected...
2014-07-12T09:07:40.228122+0000 [0.08170] Found the mime-type: application/xml; charset=UTF-8
2014-07-12T09:07:40.228251+0000 [0.08183] Made some progress, downloaded 0 so far
2014-07-12T09:07:40.228341+0000 [0.08192] Made some progress, downloaded 757 so far
<location>
<lat>44.9465193</lat>
<lng>-93.3439291</lng>
</location>
----
Took 0.11873 seconds
最后一种方法:如果您不能通过故障排除来解决问题,那么正确地包装它可能会使用更好的工作数据库替换远程服务变得更容易。但也许可以检查一下地理坐标是否与邮政编码一起工作得很好:Where can I obtain an up-to-date list of US ZIP Codes with Latitude and Longitude Geocodes?。
https://stackoverflow.com/questions/24708591
复制相似问题