What is the most efficient way to get part of a remote XML file through PHP?
This question cannot be defined specifically, as it has many consequences.
You are actually dealing with a remote service. I usually suggest always wrapping / proxing them (compare: The Daily Mistake: Not to Proxy Remote Services ). This is because they always come with many consequences. You partially do this already by transferring the data to the function:
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; }
However, this single function is not enough to solve all the problems that such a service may encounter. For instance. a remote location may simply be inaccessible, from which such a response timeout can be qualified - or, as you experience it, it will take too much time.
Therefore, you are generally not satisfied with the quality of service.
As usual with remote services, you cannot completely control them, and you have little influence on the quality of service, its packaging has advantages that you can solve with such problems in the shell to protect the rest of your logic application from all these consequences.
This requires that you not only encapsulate data parsing (for example, you started working with a function), but also search (remote request). You also need to have error handling that is not in your function. Another hint is the design for failure. For instance. your application is still running, even the information you are trying to get (add) is missing.
Another advantage of such a proxy server is that you can implement debugging functionality. For example, with the code you provided, I have no problem to quickly get the data:
$zip = '55416'; $start = microtime(true); slug_get_coordinates($zip)->asXML('php://output'); printf("\n----\nTook %.5f seconds\n", microtime(true) - $start);
Output:
<location> <lat>44.9465193</lat> <lng>-93.3439291</lng> </location> ---- Took 0.11873 seconds
If you need to look deeper into a remote request, you can connect to PHP stream notifications. I compiled StreamNotifyPrinter , which does this work and can be easily registered:
$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);
Output:
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
If this information is not enough, you may need to switch the transport level (for example, using Curl as Jack, which has a more specialized API for debugging a request, see Php - Debugging Curl).
As a last resort: if you cannot solve the problem by troubleshooting, proper completion can make it easier to replace the remote service with a better working database. But maybe check to see if the geo-coordinated work with zip codes is really geo-coordinated: Where can I get an updated list of US zip codes with geographical points and longitudes? .