jQuery, utf8 и перекодирование строки в php
Несколько часов ушло на то чтобы разобраться в чем причина того что запрос приходит то в виде вопросиков, то в виде неведомых значков то еще чего то.
Описание:
На странице форма с <input type="text" name="address" id="address" value="Russia, Moscow" />, где пользователь вбивает адрес, при клике на кнопку submit срабатывает следующий код:
jQuery.getJSON("http://test/ajax/geocode-address/query/" + jQuery('#address').val(), // тут дальше еще код, но это уже не важно
дальше отправляется запрос в базу данных итд. Для того чтобы пользователи ничего лишнего не натолкали используется такая функция:
<?php
protected function filterData($data)
{
$filterChain = new Zend_Filter();
$filterChain->addFilter(new Zend_Filter_HtmlEntities())
->addFilter(new Zend_Filter_StringToLower())
->addFilter(new Zend_Filter_StringTrim())
->addFilter(new Zend_Filter_StripTags());
return $filterChain->filter($data);
}Чтобы не хранить много повторных запросов адресов, я снижаю возможность ввода повторов за счет того что привожу все в нижний регистр и убираю пробелы
<?php$query = str_replace(' ', '', $this->filterData($query));?>
Пробую запрос "russia,москва", сразу же появляется ошибка:
<?phpZend_Db_Statement_Exception: SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding "UTF8": 0x9c HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding". in /var/www/Zend/library/Zend/Db/Statement/Pdo.php on line 238?>
Собственно говоря это ругнулся PostgreSQL на то что ему подсовывают неправильный utf-8, смотрю что послалось в запросе:
<?php'russia,&eth;�&eth;&frac34;&ntilde;�&eth;&ordm;&eth;&sup2;&eth;&deg;'?>
С этим быстро стало понятно что делать:
<?phphtml_entity_decode(rawurldecode($query), ENT_QUOTES)?>
однако это не прокатило, вернулись одни значки вопроса
string 'russia,������' (length=19)
на это
<?phphtml_entity_decode(rawurldecode($query), ENT_QUOTES, 'utf-8')?> мне были показаны другие закорючки
string 'russia,ð�ð¾ñ�ðºð²ð°' (length=29)
В общем дальше ушло несколько часов на то чтобы понять как же привести строку к нормальному виду. Причина нашлась к 6 утра и ей оказался зендовский фильтр Zend_Filter_HtmlEntities(), после того как от него избавился строка наконец таки стала выглядеть как надо
string 'russia,Москва' (length=19)