Как я могу обрабатывать unicode с Perl DBI?

My delicious-to-wp perl script работает, но дает для всех "странных" символов даже более странный результат. Поэтому я попробовал

$description = decode_utf8( $description ); 

но это не имеет значения. Я бы хотел, например, "go live", чтобы стать "go live", а не "live". Как я могу обрабатывать unicode в Perl, чтобы это сработало?

UPDATE: я обнаружил, что проблема заключалась в том, чтобы установить utf из DBI, который я должен был установить в Perl:

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

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

Ответ 1

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

Ответ 2

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

Ответ 3

Включить 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, чтобы получить тот же эффект.

Ответ 4

Термин

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

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

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

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

use open ':utf8';

и

binmode STDOUT, ":utf8";

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

Ответ 5

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

binmode STDOUT, ":utf8";

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

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

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

Ответ 6

По умолчанию драйвер 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 и рецепт выше, работал у меня.