Пытаюсь получить координаты по названию объекта в формате JSON, но в ответе геокодера вместо названия объекта набор символов. Раньше код работал, но недавно в Яндексе изменились требования и начались проблемы. техподдержка Яндекс говорит что теперь геокодер принимает только UTF-8 кодировку. Ок, настроил сервер, и внутреннюю кодировку на UTF-8. Для запроса координат, например, Санкт-Петербурга в ответ прилетает это СанкÑ-ÐеÑеÑбÑÑг. В таком формате:
array(1) { ["response"]=> array(1) { ["GeoObjectCollection"]=> array(2) { ["metaDataProperty"]=> array(1) { ["GeocoderResponseMetaData"]=> array(3) { ["request"]=> string(57) "СанкÑ-ÐеÑеÑбÑÑг" ["results"]=> string(2) "10" ["found"]=> string(1) "0" } } ["featureMember"]=> array(0) { } } } }
Тестовый код:
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('UTF-8');
mb_http_output ('UTF-8');
mb_http_input ('UTF-8');
error_reporting(E_ALL);
$user_2 = "Санкт-Петербург";
$url = 'https://geocode-maps.yandex.ru/1.x/?format=json&apikey=c910121a-bfc1-479e-a7d1-xxx&geocode='.$user_2;
$ar = json_decode(file_get_contents($url),true);
$coords = $ar['response']['GeoObjectCollection']['featureMember']['GeoObject']['Point']['pos'];
list($lon,$lat) = explode(' ',$coords);
$lon = +$lon;
$lat = +$lat;
echo "</br></br>";
print_r("Кодировка переменной 'user_2': ");
echo mb_detect_encoding($user_2);
echo "</br></br>";
print_r("Содержимое переменной 'user_2': ");
print_r ($user_2);
echo "</br></br>";
print_r("Кодировка сформированного запроса для геокодера: ");
echo mb_detect_encoding($url);
echo "</br></br>";
print_r("Вид запроса для геокодера: ");
print_r ($url);
echo "</br></br>";
print_r("Кодировка данных, полученных от геокодера: ");
echo mb_detect_encoding($ar['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['request']);
echo "</br></br>";
print_r("Содержимое массива: ");
var_dump ($ar);
Результат выполнения кода:
Notice: Undefined index: GeoObject in C:\xampp\htdocs\test\testData.php on line 11
Notice: Undefined offset: 1 in C:\xampp\htdocs\test\testData.php on line 12
Warning: A non-numeric value encountered in C:\xampp\htdocs\test\testData.php on line 13
Кодировка переменной 'user_2': UTF-8
Содержимое переменной 'user_2': Санкт-Петербург
Кодировка сформированного запроса для геокодера: UTF-8
Вид запроса для геокодера: https://geocode-maps.yandex.ru/1.x/?format=json&apikey=c910121a-bfc1-479e-a7d1-xxx&geocode=Санкт-Петербург
Кодировка данных, полученных от геокодера: UTF-8
Содержимое массива: array(1) { ["response"]=> array(1) { ["GeoObjectCollection"]=> array(2) { ["metaDataProperty"]=> array(1) { ["GeocoderResponseMetaData"]=> array(3) { ["request"]=> string(57) "СанкÑ-ÐеÑеÑбÑÑг" ["results"]=> string(2) "10" ["found"]=> string(1) "0" } } ["featureMember"]=> array(0) { } } } }
Кто подскажет как правильно кодировать запрос для геокодера? Видно что запрос сформирован в UTF-8, ответ тоже получен в UTF-8 но при этом в виде кракозябр. Сторонние кодировщики говорят что значение в массиве в кодировке ISO-8859-1, но я как понимаю ISO-8859-1 полностью совместима с UTF-8.
В результате выполнения, видно что проблема в строке 11, в массиве нет ключа GeoObject
попробуйте так:
header('Content-Type: text/html; charset=utf-8');
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
mb_http_input('UTF-8');
error_reporting(E_ALL);
$user_2 = "Санкт-Петербург";
$url = 'https://geocode-maps.yandex.ru/1.x/?format=json&apikey=c910121a-bfc1-479e-a7d1-xxx&geocode=' . $user_2;
$ar = json_decode(file_get_contents($url), true);
$coords = getRawCoords($ar);
if (empty($coords)) {
var_dump($ar);
}
list($lon, $lat) = explode(' ', $coords);
$lon = +$lon;
$lat = +$lat;
echo "</br></br>";
print_r("Кодировка переменной 'user_2': ");
echo mb_detect_encoding($user_2);
echo "</br></br>";
print_r("Содержимое переменной 'user_2': ");
print_r($user_2);
echo "</br></br>";
print_r("Кодировка сформированного запроса для геокодера: ");
echo mb_detect_encoding($url);
echo "</br></br>";
print_r("Вид запроса для геокодера: ");
print_r($url);
echo "</br></br>";
print_r("Кодировка данных, полученных от геокодера: ");
echo mb_detect_encoding($ar['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['request']);
echo "</br></br>";
print_r("Содержимое массива: ");
var_dump($ar);
function getRawCoords(array $response)
{
switch (true) {
case !isset($response['response']):
case !isset($response['response']['GeoObjectCollection']):
case !isset($response['response']['GeoObjectCollection']['featureMember']):
case !isset($response['response']['GeoObjectCollection']['featureMember']['GeoObject']):
case !isset($response['response']['GeoObjectCollection']['featureMember']['GeoObject']['Point']):
case !isset($response['response']['GeoObjectCollection']['featureMember']['GeoObject']['Point']['pos']):
return null;
default:
return $response['response']['GeoObjectCollection']['featureMember']['GeoObject']['Point']['pos'];
}
}
Таким образом, вы поймете, что за ошибка возвращается вам
Столкнулась с такой же проблемой, сервер на Tomcat. Изменение кодировки в Tomcate решило проблему:
set "CATALINA_OPTS=%CATALINA_OPTS% -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
Нужно экранировать текст запроса функцией urlencode(). В Вашем конкретном случае нужно экранировать переменную $user_2.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Изучая php, решил написать простой калькулятор на phpИмеются два input для двух значений, select для выбора математической операции и submit