Я недавно проверил один из наших веб-сайтов и понял, что поиск по почтовому индексу больше не работает.
Я получаю следующую ошибку:
«Не удалось загрузить внешнюю сущность»
Если вместо этого я использую simplexml_load_string()
Я получил
«Ожидается начальный тег»<‘ не найдено’.
Это код, который я использую:
libxml_use_internal_errors(true);
$xml = simplexml_load_file('https://nominatim.openstreetmap.org/search?postalcode=28217&country=DE&format=xml&polygon=1&addressdetails=1&boundary=postalcode');
if (false === $xml) {
$errors = libxml_get_errors();
var_dump($errors);
}
Я где-то читал, что это может иметь какое-то отношение к заголовкам HTTP, но я не нашел никакой полезной информации об этом.
В политике использования OSM Nominatim указано, что вам необходимо предоставить User-Agent
или же HTTP-Referer
заголовок запроса для идентификации приложения. Таким образом, использование пользовательского агента для маскировки под браузер конечного пользователя на самом деле не очень хороший этикет.
Вы можете найти политику использования Вот. Это также говорит о том, что значения по умолчанию используются библиотеками http (например, simplexml_load_file()
использует) не являются приемлемыми.
Вы говорите, что используете simplexml_load_string()
, но не могу сказать, как вы получаете XML для этой функции. Но наиболее вероятный сценарий заключается в том, что какой бы метод вы не использовали для получения XML-файла, вы также пренебрегаете передачей обязательных заголовков.
Таким образом, я бы создал запрос, используя PHP-завиток, предоставить один из этих заголовков для идентификации вашего приложения; и проанализировать полученную строку XML с simplexml_parse_string()
,
Например.:
// setup variables
$nominatim_url = 'https://nominatim.openstreetmap.org/search?postalcode=28217&country=DE&format=xml&polygon=1&addressdetails=1&boundary=postalcode';
$user_agent = 'ID_Identifying_Your_App v100';
$http_referer = 'http://www.urltoyourapplication.com';
$timeout = 10;
// curl initialization
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $nominatim_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
// this is are the bits you are missing
// Setting curl's user-agent
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
// you an also use this one (http-referer), it's up to you. Either one or both.
curl_setopt($ch, CURLOPT_REFERER, $http_referer);
// get the XML
$data = curl_exec($ch);
curl_close($ch);
// load it in simplexml
$xml = simplexml_load_string($data);
// This was your code, left as it was
if (false === $xml) {
$errors = libxml_get_errors();
var_dump($errors);
}
вы можете использовать curl
с добавлением пользовательского заголовка, я надеюсь, что этот код будет полезен для вас:
<?php
$request_url='https://nominatim.openstreetmap.org/search?postalcode=28217&country=DE&format=xml&polygon=1&addressdetails=1&boundary=postalcode';
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept-Language: en-US,en;q=0.9,fa;q=0.8,und;q=0.7',
'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36'));
curl_setopt($ch, CURLOPT_URL, $request_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
$data = curl_exec($ch);
curl_close($ch);
echo($data);