Я пытаюсь получить часть удаленного XML-файла, в этом случае долготу и широту для почтового индекса через Карты Google. Это функция, которую я использую в настоящее время:
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-файла, который мне нужен, не загружая все это или какой-либо другой способ оптимизировать это?
Если служба не предоставляет эту функциональность, вы не можете запросить частичный ответ на основе селектора (например, 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 ... )
С помощью этих данных вы можете разработать соответствующий подход для решения проблемы. Кэширование ответов может облегчить время запроса для повторных поисков, но может не работать для вашего конкретного случая.
Каков наиболее эффективный способ получить часть удаленного XML-файла через PHP?
На этот вопрос нельзя ответить конкретно, так как это имеет много последствий.
На самом деле вы имеете дело с удаленным сервисом здесь. Обычно я предлагаю всегда обертывать / прокси их (сравните: The Daily Mistake: Not to Proxy Remote Services ). Это потому, что они всегда приходят со многими последствиями. Вы частично это делаете, завернув процесс извлечения данных в функцию:
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. Я скомпилировал StreamNotifyPrinter, который выполняет эту работу и может быть легко зарегистрирован:
$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
Если этой информации недостаточно, вам может потребоваться переключить транспортный уровень (например, с помощью Curl, предложенного Джеком , который имеет более специализированный API для отладки запроса, см. Php – Debugging Curl ).
В крайнем случае: если вы не можете решить проблему с помощью устранения неполадок, ее надлежащее завершение может упростить замену удаленного сервиса лучшей рабочей базой данных. Но, возможно, проверка того, действительно ли геокоординируют работу с почтовыми кодами: Где я могу получить обновленный список почтовых индексов США с географическими и долготными геокодами? ,