Проблема с %uXXXX

Wicked

Новичок
Чота я ничо не пойму.
Сделал простой тест.
Закодировал "쎽ýý", получил %uC3BD%C3%BD%FD.

00C3;LATIN CAPITAL LETTER A WITH TILDE
00BD;VULGAR FRACTION ONE HALF
00FD;LATIN SMALL LETTER Y WITH ACUTE
C3BD;HANGUL SYLLABLE SSYEG

Да, херня получается :) Я думал тут UTF-8, в котором символы смешиваться не могут, ан нет...

SelenIT
Я правильно понимаю, что у тебя основная головная боль - как из %uC3BD%C3%BD%FD получить обратно 쎽ýý?
 

SelenIT

IT-лунатик :)
Нет, это-то как раз не проблема, с этим справляется мой первоначальный вариант. Проблема - различить, что собой представляет тот же %C3%BD - url-закодированный (побайтно) ý или заэскейпленные (посимвольно) ý - при отсутствии других признаков эскейпа. Если в строке есть хоть один %u... либо коды выше %С0 встречаются поодиночке - тогда все ясно. А вот когда кроме такой пары ничего нет...
 

Wicked

Новичок
чота не пойму, каким образом у тебя из ý получается %C3%BD...
 

Wicked

Новичок
Кажись разобрался.
Просто бинарно "ý" в UTF-8 равен "ý" в UCS-2BE. Угу? :)

-~{}~ 19.10.07 19:39:

Дак и в чем проблема? :))))

-~{}~ 19.10.07 19:58:

SelenIT
то что скрывается за %C3%BD - два escape'нутых символа Ã и ½ либо один URL-закодированный символ ý - можно наверняка знать, лишь зная происхождение строки
По-моему это действительно сводится к вопросу: "в какой кодировке пришла к нам строка: в UTF-8 или в UCS-2BE?". И, по сути, ты это и пытаешься решить с помощью такой извратной логики: если там %uXXXX, то UCS-2BE, и т.д.
Я прав?
 

WP

^_^
PHP:
function _gpc_decode(&$var)
{
 if (is_array($var)) {foreach ($var as $k => $v) {_gpc_decode($var[$k]);}}
 else {$var = stripslashes($var);}
}
function _urldecode_correct($s) {return preg_match('~(%u[a-f\d]{4}|%[c-f][a-f\d](?!%[89a-f][a-f\d]))~is',$s,$m)?preg_replace('~%(u[a-f\d]{4}|[a-f\d]{2})~ie','urlencode(html_entity_decode("&#".hexdec("$1").";",ENT_NOQUOTES,"utf-8"))',$s):$s;}
function _parse_str($s,&$array) {parse_str(_urldecode_correct($s),$array);}
_parse_str($_SERVER['QUERY_STRING'],$_GET);
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {_parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$_POST);}
if (isset($_SERVER['HTTP_COOKIE'])) {_parse_str(preg_replace('~;\s*~','&',$_SERVER['HTTP_COOKIE']),$_COOKIE);}
if (get_magic_quotes_gpc())
{
 _gpc_decode($_GET);
 _gpc_decode($_POST);
 _gpc_decode($_COOKIE);
}
if (version_compare(PHP_VERSION,'5.2.0','==') && !isset($GLOBALS['HTTP_RAW_POST_DATA']))
{
 _gpc_decode($_POST);
}
if (get_magic_quotes_gpc())
{
 if (isset($_SERVER['PHP_AUTH_USER'])) {$_SERVER['PHP_AUTH_USER'] = stripslashes($_SERVER['PHP_AUTH_USER']);}
 if (isset($_SERVER['PHP_AUTH_PW']))   {$_SERVER['PHP_AUTH_PW']   = stripslashes($_SERVER['PHP_AUTH_PW']);}
}
$_REQUEST = $_GET + $_POST + $_COOKIE;
Конечный вариант.
 

Rin

*
WP
>Увы там те же Котеровские яйца только сбоку...

А в чем проблема-то?
У меня эта функция уже как год нормально работает...
 

Wicked

Новичок
Информация к размышлению:

Я вот щас сделал тест на своем FF2.0.0.7.
Сделал скрипт:
Код:
<?php print urlencode($_GET[123]); ?>
<form>
<input type="text" name="123">
<input type="submit">
Открыл ее в браузере.
Поставил кодировку cp1251. Написал "абв". Засабмитил. Мне выдалось "%E0%E1%E2".
Переключился на koi-8. Написал "абв". Засабмитил. Мне выдалось "%C1%C2%D7".
Переключился на utf-8. Написал "абв". Засабмитил. Мне выдалось "%D0%B0%D0%B1%D0%B2".

В хедерах никакой информации нету :|
 

Wicked

Новичок
SelenIT
По всей видимости надо заранее знать, в каком виде данному скрипту будут посылаться данные. Вот и все.

Да, этот метод не универсален, но зато не полагается на вероятность "а вот если нам придут такие символы, то так, а если другие, то эдак".
 

WP

^_^
> В хедерах никакой информации нету :|
А что там должно быть?
 

Rin

*
> if (get_magic_quotes_gpc())

Это дурные костыли PHP.
Избавьтесь от этого раз и навсегда и нагружайте PHP лишней работой.

.htaccess
#запрещаем квотирование данных для $_GET, $_POST, $_COOKIE
php_value magic_quotes_gpc 0

Если хостер не дает доступ к .htaccess, смените -- это плохой хостер.

Какой тест, все это на живом проекте работает!
 

WP

^_^
Rin
> Избавьтесь от этого раз и навсегда и нагружайте PHP лишней работой.
get_magic_quotes_gpc() копеечная операция.
> Какой тест, все это на живом проекте работает!
Мой элементарный тест :)

> Если хостер не дает доступ к .htaccess, смените -- это плохой хостер.
Твои бы слова да клиентам в уши :)))
А у меня конечно magic_quotes_gpc = off, и вообще хочу чтоб убрать эту дибильную опцию как и register_globals.
 

Rin

*
Кстати Яндекс нормально проглатывает UTF-8, cp1251 и юникод в виде %uxxxx.

http://www.yandex.ru/yandsearch?clid=9582&text=%E0%E1%E2

Это значит, что у него есть автоопределение кодировки.
Для трёх случаев это сделать не сложно.
Если добавить к набору кодировки CP866, KOI8-R, MAC, ISO-8859-5, то придется написать что-то более умное, а нужно ли?
Эти однобайтовые кодировки сильно устарели, cp1251 еще пока применяется.
 

SelenIT

IT-лунатик :)
Wicked,
>По всей видимости надо заранее знать, в каком виде данному скрипту будут посылаться данные. Вот и все.

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

Слегка модифицировал тест:
Код:
<form>
<input name="test">
<input type="submit" value="Отослать браузером">
<input type="button" value="Отослать Javascript-ом 1"
    onclick="location=location.href.split('?')[0] + '?test='+escape(this.form.test.value)">
<input type="button" value="Отослать Javascript-ом 2"
    onclick="location=location.href.split('?')[0] + '?test='+encodeURIComponent(this.form.test.value)">
</form>
Имхо, мораль - javascript-овый escape на свалку истории, а старым браузерам (не понимающим encodeURIComponent) вообще отключать JavaScript-овые навороты, пусть работают с голым HTML или срочно апгрейдятся... :)
 
Сверху