PHP: UTF8 word wrap

Публикувано на 15 август 2008 от Ицката в Интернет и уеб
Етикети: , ,

Наложи ми се да ползвам wordwrap() функцията на php за един проект. Оказа се, че не работи коректно с unicode (utf-8). Логично, в utf-8 кодовата таблица един знак се равнява на 2 байта, за разлика от iso-8859-1, или windows-1251, където 1 знак = 1 байт. Респективно функцията режеше стринга наполовина зададената дължина.

Накратко, трябваше ми custom функция. Няколко часа търсих в нета решения, пробвах доста такива функции които уж работеха, но всъщност не работеха коректно с кирилицата. Видя се, че ще трябва да си го пиша сам.

Първото нещо, което ми дойде наум, беше просто да удвоя допустимите символи на ред. Пример, ако искам да режа стринга след 65-я знак, вместо в wordwrap() да задам като параметър 65 слагам 2 * 65 = 130. Да, но интервалите? Дори в utf-8 таблицата един интервал (шпация) = 1 байт. Не се оказа правилния подход.

Прочетох малко в php.net за multibyte функциите, и по-конкретно за mb_convert_encoding. Реших си проблема, с няколко реда:


    // Define the function. Parameters:
    // $s = The unicode string we want to wrap;
    // $w = The symbol after we want our string to wrap to the next line, default: 65 (Email Standard);
    // $b = Breaking string, default: new line ("\n");
    // $c = Boolean, whether we want our string to be cut exactly after $w character.


    function
utf8_wordwrap($s,$w=65,$b="\n",$c=false) {
        $s = mb_convert_encoding($s,'cp1251','UTF-8');
        $s = wordwrap($s,$w,$b,$c);
        return mb_convert_encoding($s,'UTF-8','cp1251');
    }

  1. PHP: RegExp проблем с кирилицата За един от последните си сайтове писах една търсачка, на php. За търсенето ползвах регулярни изрази (т. нар. regular expressions),...
  2. Публикуваха ми фунцкията в php.net http://blog.ickata.net/?p=60 – тук ви разказах за проблема с preg_match фунцкията на php, Linux сървърите и кирилицата. Накратко: ако искаме case-insensitive...