Не удалось загрузить внешнюю сущность в файле simplexml_load_file на Openstreetmap - PullRequest
0 голосов
/ 11 июня 2018

Я недавно проверил один из наших веб-сайтов и понял, что поиск по почтовому индексу больше не работает.

Я получаю следующую ошибку:

'Не удалось загрузить внешнийсущность '

Если вместо этого я использую simplexml_load_string(), я получаю

' Ожидается начальный тег, <<не найден '. </p>

Вот код, который я использую:

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, но я не нашел никакой полезной информации по этому вопросу.

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

В политике использования OSM Nominatim указано, что вам необходимо предоставить заголовок запроса User-Agent или HTTP-Referer для идентификации приложения.Таким образом, использование пользовательского агента для маскировки под браузер конечного пользователя - не очень хороший этикет.

Вы можете найти политику использования здесь .В нем также говорится, что значения по умолчанию, используемые библиотеками http (например, используемые simplexml_load_file()), недопустимы.

Вы говорите, что используете simplexml_load_string(), но не можете сказать, как вы получаете XML дляэта функция.Но наиболее вероятный сценарий заключается в том, что какой бы метод вы не использовали для получения XML-файла, вы также пренебрегаете передачей обязательных заголовков.

Поэтому я бы создал запрос, используя php-curl, предоставьте один из этих заголовков для идентификации вашего приложения;и проанализируйте полученную строку 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);
}
0 голосов
/ 13 июня 2018

вы можете использовать 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);
...