What is the most efficient way to get part of a remote XML file through PHP?

I am trying to get part of a deleted XML file, in this case the longitude and latitude for the zip code through Google Maps. This is the function that I am currently using:

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; } 

This sometimes works after a long page load, but usually this time. Is there a way to directly jump to the part of the XML file that I need without loading all of this or some other way to optimize this?

+4
source share
2 answers

If the service does not provide this functionality, you cannot request a partial response based on a selector (e.g. XPath / CSS).

In terms of efficiency, I would recommend revealing the request time in as much detail as possible in order to find out why a particular request takes some time. cURL has pretty good support for this, for example:

 $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)); 

This gives an array with all the metadata of your request:

 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 ... ) 

Using this data, you can develop an appropriate approach to solve the problem. Response caching may facilitate query time for repeated searches, but may not work for your particular case.

+2
source

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? .

+2
source

Source: https://habr.com/ru/post/973146/


All Articles