<rmcreative>

RSS

Все заметки с тегом «urldecode»

Можно уточнить:

    (1)
    (1)
  1. urldecode и кодировки

    9 июля 2011

    Сегодня неожиданно много времени провёл за изучением одного из репортов в трекере Yii. Первопричина оказалась совсем не той и крылась, как это часто бывает, в несоблюдении стандартов. Вообще тонкости две:

    1. PHP-шный urldecode работает напрямую с октетами (теми, что %AB), так что интерпретация строки зависит от кодировки скрипта. В случае Yii это UTF-8.

    2. Хоть RFC 3986 в районе 16-ой страницы и говорит нам, что «data should first be encoded as octets according to the UTF-8 character encoding», но всё-же достаточно большое количество ПО использует другие кодировки. Чаще всего это ISO-8859-1.

    То есть после декодирования мы можем получить либо UTF-8, либо что-то ещё. Это ещё скорее всего будет ISO-8859-1.

    Ну и решение — свой urldecode:

    /**
     * Improved variant of urldecode.
     * Properly decodes both UTF-8 and ISO-8859-1 encoded URIs.
     *
     * @param string $str encoded string
     * @return string decoded string
     */
    private function urldecode($str)
    {
        $str = urldecode($str);
     
        // is it UTF-8?
        // http://w3.org/International/questions/qa-forms-utf-8.html
        if(preg_match('%^(?:
           [\x09\x0A\x0D\x20-\x7E]            # ASCII
         | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
         | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
         | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
         | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
         | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
         | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
         | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
        )*$%xs', $str))
        {
            return $str;
        }
        else
        {
            return utf8_encode($str);
        }
    }
    3 комментария