проблемма с русским языком в обрезаных заголовках

Тема в разделе "Коммерческие", создана пользователем krushanovskij, 4 фев 2010.

Информация :
Публиковать (для всех) нуленые версии, особенно от modulesgarden КАТЕГОРИЧЕСКИ не стоит. Тема мониторится оным разработчиком, а к нам приходят абузы которые нельзя игнорировать.
Статус темы:
Закрыта.
Модераторы: Amazko, Aste
  1. krushanovskij

    krushanovskij Создатель

    Регистр.:
    26 фев 2009
    Сообщения:
    16
    Симпатии:
    0
    добрый вечер, коллеги, не знаю, в той ли теме я создал сообщение, но, так как других подходящих тем для постинга я не нашел - прошу помощи тут.
    у меня есть сайт. на нем стоит скрипт phpmelody 1.6
    шикарный скрипт, но в нем есть один недостаток.
    русские буквы в заголовках, которые обрезаются - отображаются некоректно.
    а именно: РазвÑ�аÑ�наÑ.. (и подобые символы)
    опытным путем я понял - что это проблемма кодировки, именно - latin1 или как ее еще называют ISO-8859-1
    хотя должна быть UTF8.
    в базе данных все нормально, русский текст отображается как надо, вся база в utf8_general_ci.
    я уже несколько дней ломаю себе над этим голову - все никак не осилю.
    повторюсь, и уточню еще раз:
    пролемма возникает ТОЛЬКО в русских заголовках. и ТОЛЬКО в тех - которые обрезаются(насколько я понял - плагином Smarty - modifier.truncate.php)
    ps: модераторы, если моя тема не подходит для этого раздела, или в другом мне смогут помочь более - перенесите ее пожалуйста.
    pps: прошу не отвечать тех людей - которые не разбираются в теме, и не могут реально помочь.
    заранее спасибо.
     
  2. PapaJoe

    PapaJoe

    Регистр.:
    4 авг 2008
    Сообщения:
    620
    Симпатии:
    312
    Здесь проблема в функции "обрезания", а точнее в кодировке utf-8: русские символы этой кодировки записываются 2-мя байтами, а т.к. ваша функция не знает об этом, она может отрезать половину буквы(1 байт от буквы). Такая проблема встречалась мне при работе с wap-сайтами. К примеру, браузер Opera выведет только обрезанный символ кракозябрами, а firefox может весь заголовок "поломать".

    Одним из решений может быть сначала конвертация, например, в windows-1251 кодировку, обрезание, конвертация обратно в utf-8.
    Первое решение, которое пришло на ум.
     
  3. krushanovskij

    krushanovskij Создатель

    Регистр.:
    26 фев 2009
    Сообщения:
    16
    Симпатии:
    0
    спасибо конечно, но, помойму - это не вариант, так как это чересчур сложно.
    может у Вас еще есть идеи по этому поводу?

    кстати, как вариант - еще можно полность попробовать конвертнуть всю базу в WIN1251, и в конфиге тоже прописать вместо UTF-8, WINDOWS1251, что Вы думаете по этому поводу?
     
  4. PapaJoe

    PapaJoe

    Регистр.:
    4 авг 2008
    Сообщения:
    620
    Симпатии:
    312
    Вспомнил, есть такая функция как mb_substr, как раз для работы с кодировками типа utf-8
    Если phpmelody обрезает заголовки функцией substr, то просто следует заменять substr на mb_substr
    http://ru2.php.net/mb_substr
    Важная особенность, 4-ым параметром этой функции должна указываться кодировка строки, с которой предстоит работа, например:
    PHP:
    $a mb_substr($b,0,2,'UTF-8');
    или же заранее установить кодировку для таких функций: mb_internal_encoding("UTF-8");
     
  5. krushanovskij

    krushanovskij Создатель

    Регистр.:
    26 фев 2009
    Сообщения:
    16
    Симпатии:
    0
    я так понял, я могу в конфиге просто прописать где угодно mb_internal_encoding("UTF-8");
    и все будет гуд?
    или не в конффиге?
     
  6. PapaJoe

    PapaJoe

    Регистр.:
    4 авг 2008
    Сообщения:
    620
    Симпатии:
    312
    Ну это уже где удобнее, главное - до вызова функции mb_substr
     
  7. krushanovskij

    krushanovskij Создатель

    Регистр.:
    26 фев 2009
    Сообщения:
    16
    Симпатии:
    0
    дело в том, что я не могу похвастаться глубокими познаниями в пхп. и в данном случае попросту не представляю, куда нужно его запихнуть.
    это целая строка? перед ней, или после нее ниче не нужно всталять?
    просто я не знаю, либо в плагины смарти ее засунуть, либо в сеттингс, либо ще куда...
     
  8. PapaJoe

    PapaJoe

    Регистр.:
    4 авг 2008
    Сообщения:
    620
    Симпатии:
    312
    ИМХО, должно работать если закинуть в "сеттингс" и если он подгружается в начале файла.
    вы главное не забудьте substr на mb_substr заменить, а то от одного mb_internal_encoding("UTF-8"); толку мало. ;)
     
  9. krushanovskij

    krushanovskij Создатель

    Регистр.:
    26 фев 2009
    Сообщения:
    16
    Симпатии:
    0
    вот действиями этого файла я обрезаю строку. Можете на примере показать, что и как, пожалуйста.

    PHP:
    <?php
    /**
     * Smarty plugin
     * @package Smarty
     * @subpackage plugins
     */


    /**
     * Smarty truncate modifier plugin
     *
     * Type:     modifier<br>
     * Name:     truncate<br>
     * Purpose:  Truncate a string to a certain length if necessary,
     *           optionally splitting in the middle of a word, and
     *           appending the $etc string or inserting $etc into the middle.
     * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
     *          truncate (Smarty online manual)
     * @author   Monte Ohrt <monte at ohrt dot com>
     * @param string
     * @param integer
     * @param string
     * @param boolean
     * @param boolean
     * @return string
     */
    function smarty_modifier_truncate($string$length 80$etc '...',
                                      
    $break_words false$middle false)
    {
        if (
    $length == 0)
            return 
    '';

        if (
    strlen($string) > $length) {
            
    $length -= min($lengthstrlen($etc));
            if (!
    $break_words && !$middle) {
                
    $string preg_replace('/\s+?(\S+)?$/'''mb_substr($string0$length+1));
            }
            if(!
    $middle) {
                return 
    mb_substr($string0$length) . $etc;
            } else {
                return 
    mb_substr($string0$length/2) . $etc mb_substr($string, -$length/2);
            }
        } else {
            return 
    $string;
        }
    }

    /* vim: set expandtab: */

    ?>
    в этом файле я уже заменил substr на mb_substr.
    файлик называется modifier.truncate.php
     
  10. PapaJoe

    PapaJoe

    Регистр.:
    4 авг 2008
    Сообщения:
    620
    Симпатии:
    312
    ну вот, после <?php надо воткнуть mb_internal_encoding("UTF-8");
    на примере:
    PHP:
    <?php
    mb_internal_encoding
    ("UTF-8");
    function 
    smarty_modifier_truncate($string$length 80$etc '...',
                                      
    $break_words false$middle false)
    {
        if (
    $length == 0)
            return 
    '';
        if (
    strlen($string) > $length) {
            
    $length -= min($lengthstrlen($etc));
            if (!
    $break_words && !$middle) {
                
    $string preg_replace('/\s+?(\S+)?$/'''mb_substr($string0$length+1));
            }
            if(!
    $middle) {
                return 
    mb_substr($string0$length) . $etc;
            } else {
                return 
    mb_substr($string0$length/2) . $etc mb_substr($string, -$length/2);
            }
        } else {
            return 
    $string;
        }
    }
    ?>
    или просто добавить 4-й параметр в функцию mb_substr
    PHP:
    <?php
    function smarty_modifier_truncate($string$length 80$etc '...',
                                      
    $break_words false$middle false)
    {
        if (
    $length == 0)
            return 
    '';
        if (
    strlen($string) > $length) {
            
    $length -= min($lengthstrlen($etc));
            if (!
    $break_words && !$middle) {
                
    $string preg_replace('/\s+?(\S+)?$/'''mb_substr($string0$length+1,"UTF-8"));
            }
            if(!
    $middle) {
                return 
    mb_substr($string0$length,"UTF-8") . $etc;
            } else {
                return 
    mb_substr($string0$length/2,"UTF-8") . $etc mb_substr($string, -$length/2,,"UTF-8");
            }
        } else {
            return 
    $string;
        }
    }
    ?>
    оба варианта должны работать
     
Статус темы:
Закрыта.