Подтвердить что ты не робот

Контрольный список для перехода в Unicode с помощью Perl

Я помогаю клиенту преобразовать свой сайт доски объявлений с плоским файлом Perl из ISO-8859-1 в Unicode.

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

Это то, что я сделал до сих пор (простите меня за включение только "сводных" примеров кода):

  • Убедитесь, что файлы всегда читаются и записываются в UTF-8:

    use open ':utf8';
    
  • Убедитесь, что вход CGI получен как UTF-8 (сайт не использует CGI.pm):

    s{%([a-fA-F0-9]{2})}{ pack ("C", hex ($1)) }eg;    # Kept from existing code
    s{%u([0-9A-F]{4})}{ pack ('U*', hex ($1)) }eg;     # Added
    utf8::decode $_;
    
  • Убедитесь, что текст напечатан как UTF-8:

    binmode STDOUT, ':utf8';
    
  • Убедитесь, что браузеры интерпретируют мой контент как UTF-8:

    Content-Type: text/html; charset=UTF-8
    <meta http-equiv="content-type" content="text/html;charset=UTF-8">
    
  • Убедитесь, что формы отправляют UTF-8 (возможно, не обязательно, если установлена ​​кодировка страницы):

    accept-charset="UTF-8"
    
  • Не думаю, что мне нужно следующее, поскольку встроенный текст (меню, заголовки и т.д.) находится только в ASCII:

    use utf8;
    

Это выглядит разумно или я что-то не хватает?

EDIT: Я должен, вероятно, также упомянуть, что мы будем запускать одноразовый пакет для чтения всех существующих файлов текстовых данных и сохранения их в кодировке UTF-8.

4b9b3361

Ответ 1

  • Уровень :utf8 PerlIO not достаточно строгий. Он допускает ввод, который удовлетворяет структурным требованиям последовательностей байтов UTF-8, но для хорошей защиты вы хотите отклонить материал, который на самом деле не является действительным Unicode. Замените его повсюду слоем PerlIO::encoding, таким образом: :encoding(UTF-8).

  • По той же причине всегда Encode::decode('UTF-8', …), а не Encode::decode_utf8(…).

  • Сделать декодирование неудачным с исключением, сравните:

    perl -E'use Encode qw(decode); say decode(q(UTF-8), qq(\x{c0})); say q(survived)'
    perl -E'use Encode qw(decode); say decode(q(UTF-8), qq(\x{c0}), Encode::FB_CROAK); say q(survived)'
    
  • Вы не заботитесь о суррогатных парах в обозначениях %u. Это единственная серьезная ошибка, которую я вижу в вашем списке. 2. написано правильно:

    use Encode qw(decode);
    use URI::Escape::XS qw(decodeURIComponent);
    $_ = decode('UTF-8', decodeURIComponent($_), Encode::FB_CROAK);
    
  • Не вмешивайтесь в функции из модуля utf8. В его документации так говорится. Он предназначен как прагма для указания Perl, что исходный код находится в UTF-8. Если вы хотите сделать кодирование/декодирование, используйте модуль Encode.

  • В любом случае добавьте прагму utf8 в каждом модуле. Это не может повредить, но вы будете поддерживать будущий код в случае, если кто-то добавит эти строковые литералы. См. Также CodeLayout::RequireUseUTF8.

  • Используйте encoding::warnings, чтобы выкурить оставшиеся неявные обновления. Подтвердите для каждого случая, нужно ли это/необходимо. Если да, преобразуйте его в явное обновление с помощью Unicode::Semantics. Если нет, это намек на то, что раньше вы должны были выполнить шаг декодирования. Документы из http://p3rl.org/UNI дают совет немедленно декодировать после получения данных из источника. Перейдите по местам, где код считывает/записывает данные и проверяет, что у вас есть шаг декодирования/кодирования, либо явно (decode('UTF-8', …)), либо неявно через слой (use open pragma, binmode, 3 аргумента формы open).

  • Для отладки: если вы не знаете, какая строка находится в переменной, в которой представление в определенное время, вы не можете просто print, используйте инструменты Devel::StringInfo и Devel::Peek.

Ответ 2

Ты всегда чего-то пропускаешь. Проблема, как правило, неизвестные неизвестные.:)

Эффективное программирование на Perl содержит раздел Unicode, который охватывает многие основы Perl. Один элемент, который мы не рассматривали, - это все, что вам нужно сделать, чтобы ваш сервер базы данных и веб-сервер поступали правильно.

Некоторые другие вещи, которые вам нужно сделать:

  • Обновите свой последний Perl. Unicode стало намного проще в 5.8, а еще проще в 5.10.

  • Убедитесь, что содержимое сайта преобразовано в UTF-8. Вы можете написать сканер для попадания страниц и поиска символа замещения Юникода (эта вещь, которая выглядит как алмаз с вопросительным знаком в нем). Посмотрим, смогу ли я сделать это в StackOverflow: & # xfffd;

  • Убедитесь, что ваш сервер базы данных поддерживает UTF-8, что вы настроили таблицы с столбцами, поддерживающими UTF-8, и что вы сообщаете DBI использовать поддержку UTF-8 в своем драйвере (некоторые из этих находится в книге).

  • Убедитесь, что все, что смотрит на @ARGV, переводит элементы из локали командной строки в UTF-8 (это в книге).

Если вы найдете что-нибудь еще, сообщите нам, ответив на свой вопрос тем, что мы оставили.;)