Unserialize и кириллица

Рейтинг: 1Ответов: 1Опубликовано: 29.11.2014

Всем привет. Пытаюсь вытащить из БД сериализованную строку и десериализовать ее. Все отлично работает, если строка на латинице. Если кириллица, то получаю false. Я так понимаю, что проблема с кодировками. Собственно, как решить? Читал, что кому-то помогло mysqli_query($link, "SET NAMES cp1251");, ставил, результат тот же..

<?php 
header('Content-type: text/html; charset=utf-8');
$name = $_POST['name'];

$link = mysqli_connect("localhost", "user", "password");

if(mysqli_connect_errno()) {
 header("Location: create.php?success=-1");
 exit;
}

$query = "SELECT cities FROM `agency`.`countries` WHERE name = '$name'";
$result = mysqli_query($link, $query);
while($row = mysqli_fetch_array($result)) {
    $res = unserialize($row['cities']);
}

$res = json_encode($res);
echo $res;

?>

Обновление

Попробовал решить проблему функцией mysqli_set_charset, без изменений.

Обновление

Решил заменить serialize и unserialize на implode и explode, так как не вижу никаких ошибок в принципе. Если будут какие-то догадки пишите, интересно же, в чем причина.

Ответы

▲ 1Принят

Попробуйте SET NAMES utf8, в mysqli, по-моему, есть специальная функция, выставляющая чарсет соединения, лучше вообще ею пользоваться. А "кому-то помогло" - это изначально провальный подход.

Обновление

Да черт его знает, но я бы грешил на разность кодировок. serialize-unserialize в одну строку работает?

Решил заменить serialize и unserialize на implode и explode

Вы там что, айдишники/теги через запятую храните? Good luck with that.

Обновление

Проверьте кодировку БД и принудительно задавайте кодировку при любом коннекте, лучше всего ставить utf8 и не знать проблем. По идее, что-то рвется на пути "в бд - из бд", потому что unserialize должно быть побоку, откуда пришли байты (строка), прямо из ближайшего serialize или из БД. Можете даже unit-тест написать на соответствие строки и строки, положенной и выуженной из БД.

Обновление

Кодировки - это всегда боль, и единственное правило, которое позволяет закрыть глаза на внутренние процессы и не обращать на них внимание - это ставить везде utf-8 (в mysql - utf8). Что значит не выберет кириллицу? В каком-нибудь PHPMyAdmin / консольной строке удается получить правильный вывод? Если у вас база в utf-8, а вы засовываете туда cp1251, ничего хорошего не выйдет (вообще не уверен, что utf8 должен такое глотать, у него вроде строгие ограничения по первому байту, которые здесь не будут выполняться).

Unit-test - это такой тест, который прогоняется внутри приложения и убеждается, что отдельный модуль работает как надо. Я не буду рассказывать подробно, информации в интернете полно, можно просто написать такой тест на запись в базу и возврат значений из нее и пинать приложение, пока тест не пройдет. Хотя писать юнит-тесты на БД на самом деле нельзя )