Почему Encode :: decode ('UTF-8', $ var) все еще нужен, когда все уже в UTF-8? - PullRequest
3 голосов
/ 26 июня 2011

В поддерживаемом мной веб-приложении я стараюсь сохранить все в UTF-8:

  • База данных (CHARSET = utf8)
  • исходные файлы (используйте utf8; написано в utf8)
  • шаблоны (для Template Toolkit с использованием ENCODING => utf8)
  • пользовательский ввод и вывод (charset = utf8 заголовок в HTTP, binmode: utf8 для STDIN и STDOUT)

Но мне все еще нужно использовать Encode :: decode ('UTF-8', $ data) для данных, поступающих из базы данных, иначе они будут дважды закодированы или каким-либо образом повреждены.

Почему это? Как я могу избавиться от этого раздражающего дополнительного шага? Разве не должен быть способ хранить все, каждый раз в UTF-8 без необходимости что-либо конвертировать вручную?

Ответы [ 3 ]

3 голосов
/ 27 июня 2011

Чтобы правильно получить utf-8 из базы данных, вам нужно при подключении явно сказать ему:

my $dbh = DBI->connect( "dbi:mysql:dbname=$db;host=localhost",
       "user", "pwd", {mysql_enable_utf8 => 1 })

Как я и задавал в своем вопросе здесь , с ним все еще есть некоторые проблемы,но в большинстве случаев это работает нормально.

Ответить «почему» - часть намного сложнее.Как отметил Денис, в последнее время была довольно тяжелая тема о «почему».Может быть, это поможет вам понять связанные вещи.Я предлагаю использовать модуль utf8::all `, чтобы работать с utf-8 намного проще и чище.

2 голосов
1 голос
/ 27 июня 2011

Внутренне , ваша база данных, вероятно, будет хранить все данные в фиксированном необработанном формате, обычно UCS-4 (то есть необработанные строки 32-битных целых чисел, содержащих по одной кодовой точке каждый). UTF8 является кодировкой , и кодировки используются только при сериализации данных (например, в файле или базе данных). Десериализация, то есть чтение, означает декодирование закодированных данных и получение строки необработанного кода.

То, что вы используете одну и ту же кодировку для всех ваших нужд сериализации, не мешает вам декодировать при загрузке и кодировать при записи.

...