Определение кодировки.

Тема в разделе "PHP Pro", создана пользователем trooll, 19 дек 2010.

Статус темы:
Закрыта.
  1. trooll

    trooll PHP кодер

    Регистр.:
    22 дек 2008
    Сообщения:
    503
    Симпатии:
    116
    Доброго времени суток.

    Вопрос такого плана, как определиться кодировку строки в частности html страницы (желательно с точностью 90%) средствами PHP.

    Сразу хочу сказать что определение с помощью mb_ функций или выпарской значения тега <meta http-equiv="Content-Type" content="text/html; charset=???" /> не подходит.
     
  2. potuga

    potuga

    Регистр.:
    22 сен 2009
    Сообщения:
    376
    Симпатии:
    91
    гугл уже не тру?

    первый же результат: http://php.su/articles/?cat=examples&page=002
     
  3. trooll

    trooll PHP кодер

    Регистр.:
    22 дек 2008
    Сообщения:
    503
    Симпатии:
    116
    Гугл как раз тру! Этим сейчас и занимаюсь.

    По выше переведенному примеру:
    Функция не определяет utf-8.
     
  4. t3s

    t3s

    Регистр.:
    16 фев 2008
    Сообщения:
    719
    Симпатии:
    290
    а какая вообще задача стоИт?
    для какого-нить парсера я бы не заморачивался и действительно брал бы значение метатега - дешево и сердито...

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

    возможно поможет
    http://popoff.donetsk.ua/text/work/libs/a/charset/
     
  5. trooll

    trooll PHP кодер

    Регистр.:
    22 дек 2008
    Сообщения:
    503
    Симпатии:
    116
    Да вот просто и выпарсивал мета тег, но споткнулся сегодня на такой вот задачке:

    Есть некий сайт:
    _http://www.arigus-tv.ru/news/detail.php?ID=3730&sphrase_id=2120
    Егошняя мета в разметки html:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    А на самом деле кодировка страницы:
    windows-1251

    Скрипт выпарсивает мету и как послушный работник конвертирует из указанной кодировки в мета теге в необходимую в итоге получает сыр бор, так как на самом деле кодировка у страницы windows-1251


    Идея с:
    _http://popoff.donetsk.ua/text/work/libs/a/charset/
    интересная но не подходит так как требуется подключение дополнительной библиотеки.
     
  6. B0nuse

    B0nuse Постоялец

    Регистр.:
    6 июн 2009
    Сообщения:
    105
    Симпатии:
    21
  7. saen

    saen

    Регистр.:
    6 авг 2006
    Сообщения:
    756
    Симпатии:
    129
    Вот это почитай для начала, если не поможет, будем думать дальше.
    http://habrahabr.ru/blogs/php/107945/
    http://ivr.webzone.ru/articles/defcod_2/index.htm


    1) Раз ТС пишет что нужно определить кодировку, значит ее именно надо определить, а не конвертировать.
    2) Это не велосипед, поскольку стандартные функции в php для определения кодировки текста работают некорректно.
     
    trooll нравится это.
  8. trooll

    trooll PHP кодер

    Регистр.:
    22 дек 2008
    Сообщения:
    503
    Симпатии:
    116
    Как правильно заметил saen кодировку необходимо именно определить, а конвертировать в необходимую это уже следующий этап который не так сложен.

    Если на чистоту то дело в следующем:
    Отталкиваясь от предыдущего своего поста добавлю к нему следующее. Сейчас работаю на скриптом постера (чего именно я думаю не для кого не секрет https://www.nulled.cc/showthread.php?t=185873), при разборе полетов скрипта собственно наткнулся на данную проблему (см. Старт пост).

    Ну так почему именно необходимо именно определить кодировку? По причине того что на выходе скрипт должен сконвертить валидные данные для постинга, а точнее на данном этапе перевести данные в правильную кодировку. Ну и естественно второй момент это валидная работа с данными страницы. Можно конечно привести данные страницы к единой кодировки использую решение которое предложил B0nuse что корректно позволит работать в плане распарски и т.д. но как не крути удаленному серверу не объяснишь что ты от него хочешь подсовывая данные в непонятной кодировки.
     
  9. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.403
    Симпатии:
    1.183
    В случае с http://www.arigus-tv.ru/news/detail.php?ID=3730&sphrase_id=2120 кодировка устанавливается в HTTP-headers строкой:
    можно положится на то, что вебмастер позаботился о своих пользователях и хоть где то установил верную кодировку и парсить еще и HTTP-headers.
     
  10. CrashX

    CrashX В прошлом XSiteCMS

    Регистр.:
    6 июн 2008
    Сообщения:
    682
    Симпатии:
    112
    наткнулся на несколько вещей сразу

    это фикс для кодировки

    PHP:
    // Fixes the encoding to uf8 
    function fixEncoding($in_str

      
    $cur_encoding mb_detect_encoding($in_str) ; 
      if(
    $cur_encoding == "UTF-8" && mb_check_encoding($in_str,"UTF-8")) 
        return 
    $in_str
      else 
        return 
    utf8_encode($in_str); 
    // fixEncoding
    варианты проверки
    PHP:
    /**
         * Проверка данных на принадлежность классу символов ASCII
         * Для значений null, integer, float, boolean возвращает TRUE.
         *
         * Массивы обходятся рекурсивно, если в хотябы одном элементе массива
         * его значение не ASCII, возвращается FALSE.
         *
         * @param   array|scalar|null  $data
         * @return  bool
         */
        
    public static function is_ascii($data)
        {
            if (! 
    ReflectionTypehint::isValid()) return false;
            if (
    is_array($data))
            {
                foreach (
    $data as $k => &$v)
                {
                    if (! 
    self::is_ascii($k) || ! self::is_ascii($v)) return false;
                }
                return 
    true;
            }
            
    #if (is_string($data)) return preg_match('/^[\x00-\x7f]*$/sSX', $data);
            
    if (is_string($data)) return ltrim($data"\x00..\x7f") === '';  #small speed improve
            
    if (is_scalar($data) || is_null($data)) return true;  #~ null, integer, float, boolean
            
    return false#object or resource
        
    }

        
    /**
         * Returns true if data is valid UTF-8 and false otherwise.
         * Для значений null, integer, float, boolean возвращает TRUE.
         *
         * Массивы обходятся рекурсивно, если в хотябы одном элементе массива
         * его значение не в кодировке UTF-8, возвращается FALSE.
         *
         * @link    http://www.w3.org/International/questions/qa-forms-utf-8.html
         * @link    http://ru3.php.net/mb_detect_encoding
         * @link    http://webtest.philigon.ru/articles/utf8/
         * @link    http://unicode.coeurlumiere.com/
         * @param   array|scalar|null  $data
         * @param   bool               $is_strict  строгая проверка диапазона ASCII?
         * @return  bool
         */
        
    public static function is_utf8($data$is_strict true)
        {
            if (! 
    ReflectionTypehint::isValid()) return false;
            if (
    is_array($data))
            {
                foreach (
    $data as $k => &$v)
                {
                    if (! 
    self::is_utf8($k$is_strict) || ! self::is_utf8($v$is_strict)) return false;
                }
                return 
    true;
            }
            if (
    is_string($data))
            {
                if (
    $data === '') return true#speed improve

                
    if ($is_strict && preg_match('/[^\x09\x0A\x0D\x20-\xBF\xC2-\xF7]/sSX'$data)) return false;

                
    #the fastest variant:
                
    if (function_exists('mb_check_encoding')) return mb_check_encoding($data'UTF-8');
                if (
    function_exists('iconv')) return @iconv('UTF-8''UTF-16'$data) !== false#TODO: check work with test

                /*
                Рег. выражения имеют внутренние ограничения на длину повторов шаблонов поиска *, +, {x,y}
                равное 65536, поэтому используем preg_replace() вместо preg_match()
                */
                
    $result $is_strict preg_replace('/(?>' self::$char_re '
                                                        #| (.) # catch bad bytes
                                                       )+/sxSX'
    ''$data)
                                     : 
    #the current check allows only values in the range U+0 to U+10FFFF, excluding U+D800 to U+DFFF.
                                     
    preg_replace('/\X+/suSX'''$data); #\X is equivalent to \P{M}\p{M}*+
                
    if (function_exists('preg_last_error'))
                {
                    if (
    preg_last_error() === PREG_NO_ERROR) return $result === '';
                    if (
    preg_last_error() === PREG_BAD_UTF8_ERROR) return false;
                }
                elseif (
    is_string($result)) return $result === '';

                
    #в этом месте произошла ошибка выполнения регулярного выражения
                #проверяем ещё одним, самым медленным способом:
                
    return self::check($data$is_strict);
            }
            if (
    is_scalar($data) || is_null($data)) return true;  #~ null, integer, float, boolean
            
    return false#object or resource
        
    }

    взято из http://forum.dklab.ru/php/advises/Php-funktsiiDlyaObrabotkiTekstaVKodirovkeUtf-8.html
     
    trooll нравится это.
Статус темы:
Закрыта.