Как я могу обработать Unicode с DBI Perl? - PullRequest
16 голосов
/ 12 июня 2009

Мой Скрипт Perl "восхитительный для wp" работает, но дает для всех "странных" символов даже более странный вывод. Поэтому я попытался

$description = decode_utf8( $description ); 

но это не имеет значения. Я хотел бы, например, «Иди живым», чтобы стать «иди живым», а не «живи» Как я могу обработать Unicode в Perl, чтобы это работало?

ОБНОВЛЕНИЕ: я обнаружил, что проблема заключалась в том, чтобы установить utf DBI, который я должен был установить в Perl:

my $sql = qq{SET NAMES 'utf8';};
$dbh->do($sql);

Это была часть, которую я должен был установить, сложно. Спасибо!

Ответы [ 6 ]

19 голосов
/ 12 июня 2009

Стоит отметить, что если вы работаете с достаточно новой версией DBD :: mysql (включенной 3.0008), вы можете сделать следующее: $dbh->{'mysql_enable_utf8'} = 1;, а затем все будет декодировано выход из / в DBI.

13 голосов
/ 20 июня 2012

Включить UTF8, когда вы подключаетесь к базе данных следующим образом:

my $dbh = DBI->connect(
    "dbi:mysql:dbname=db_name", 
    "db_user", "db_pass",
     {RaiseError => 0, PrintError => 0, mysql_enable_utf8 => 1}
 ) or die "Connect to database failed.";

Это должно привести к появлению строк символьного режима с установленным флагом UTF8.

С Общие правила и предостережения DBI :

Perl поддерживает два типа строк: Unicode (внутренне utf8) и не-Unicode (по умолчанию iso-8859-1, если принудительно принять кодировку). Драйверы должны принимать оба типа строк и, если необходимо, преобразовывать их в набор символов используемой базы данных. Аналогично, при извлечении из базы данных символьных данных, отличных от iso-8859-1, драйвер должен преобразовать их в utf8.

И особенности из DBD :: mysql для mysql_enable_utf8

Кроме того, включение этого флага говорит MySQL, что входящие данные должны рассматриваться как UTF-8. Это вступит в силу, только если используется как часть вызова connect (). Если вы включите флаг после подключения, вам нужно будет выполнить команду SET NAMES utf8, чтобы получить тот же эффект.

5 голосов
/ 06 января 2011

Срок

$dbh->do(qq{SET NAMES 'utf8';});

определенно экономит день для доступа к объявленной базе данных utf-8, но обратите внимание, если вы собираетесь выполнять какую-либо perl-обработку любых данных, полученных из базы данных , было бы разумно сохранить их переменная perl как строка utf8 с, поскольку эта операция не является неявной.

$utfstring = decode('utf8',$string_from_db);

конечно, для правильной обработки ввода / вывода строк utf8 (чтение, печать, запись в вывод) не забудьте установить

use open ':utf8';

и

binmode STDOUT, ":utf8";

последний необходим для распечатки строк utf8. Надеюсь, это поможет.

3 голосов
/ 12 июня 2009

Это может не иметь никакого отношения к Perl. Убедитесь, что вы используете кодировки UTF в соответствующих столбцах таблицы MySQL.

1 голос
/ 12 мая 2011

Оставьте это в покое:

binmode STDOUT, ":utf8";

при использовании:

$dbh->do(qq{SET NAMES 'utf8';});

В противном случае ваш вывод будет иметь двойную кодировку utf8, что приведет к нечитаемым двухбайтовым символам! Мне понадобилось пару часов, чтобы понять это ..

0 голосов
/ 11 февраля 2016

По умолчанию драйвер Perl / MySQL обрабатывает двоичные данные (по крайней мере, я сделал это из некоторых экспериментов с MySQL 5.1 и 5.5).

Без установки mysql_enable_utf8 я кодировал / декодировал строки в / из UTF-8 перед записью / чтением в / из базы данных.

Не следует полагаться на представление строки внутри perl в виде массива байтов; имейте в виду, что внутренний utf8 не гарантированно является стандартом UTF-8; и наоборот, гарантируется, что однобайтовая кодировка не будет соответствовать ISO-8859-1; действительно кодировать / декодировать в / из UTF-8 (а не 'utf8').

Есть также некоторые настройки MySQL (например, SET NAMES выше, насколько я помню, есть кодировка клиента, кодировка соединения и кодировка сервера, чьи взаимодействия мне не совсем понятны, если они не все имеют то же значение) относительно кодировок; установка всех их в UTF-8, и рецепт выше, работал для меня.

...