WP
^_^
Утренний разнос GPC.
Такая вроде бы простая вещь как прием данных GPC (Get-Post-Cookie) при рассмотрении оказывается не такой простой.
Я считаю что magic_quotes_*, register_globals это зло, и что любой нормальный человек посторается их выключить или иным способом избавиться. Но к сожалению доступ к настройкам есть не везде, а нужно добиться максимальной портируемости - поэтому нужно обращать действие magic_quotes_* уже в скрипте. А также стоит напомнить о %uXXXX (это разновидность urlencode): ее использует javascript и воизбежание проблем нужно обрабатывать такие последовательности в скрипте. Если воспользоваться лежащим на поверхности решением пройдясь по массивам $_GET/$_POST/$_COOKIE - появится такая проблема: если отправить %25u1234 то PHP преобразует это в %u1234, а наш скрипт декодирует, в результате запрос будет неправильно обработан. Поэтому нужно обрабатывать QUERY_STRING для GET. А POST-данные из - HTTP_RAW_POST_DATA.
HTTP_RAW_POST_DATA доступна не всегда, поэтому ее можно опустить и при обычных запросах (не от спец. библеотеки JS) не обрабатывать %uXXXX.
В результате:
Это нужно использовать всегда. Реализации встроенные в серверные части AJAX следует закомментировать.
Принимаются замечания/дополнения. Спасибо за внимание.
-~{}~ 18.12.06 08:24:
З.Ы. надеюсь с выходом PHP 6 код полностью потеряет актуальность: magic_quotes уже убрали, осталось лишь добавить поддержку %uXXXX.
Такая вроде бы простая вещь как прием данных GPC (Get-Post-Cookie) при рассмотрении оказывается не такой простой.
Я считаю что magic_quotes_*, register_globals это зло, и что любой нормальный человек посторается их выключить или иным способом избавиться. Но к сожалению доступ к настройкам есть не везде, а нужно добиться максимальной портируемости - поэтому нужно обращать действие magic_quotes_* уже в скрипте. А также стоит напомнить о %uXXXX (это разновидность urlencode): ее использует javascript и воизбежание проблем нужно обрабатывать такие последовательности в скрипте. Если воспользоваться лежащим на поверхности решением пройдясь по массивам $_GET/$_POST/$_COOKIE - появится такая проблема: если отправить %25u1234 то PHP преобразует это в %u1234, а наш скрипт декодирует, в результате запрос будет неправильно обработан. Поэтому нужно обрабатывать QUERY_STRING для GET. А POST-данные из - HTTP_RAW_POST_DATA.
HTTP_RAW_POST_DATA доступна не всегда, поэтому ее можно опустить и при обычных запросах (не от спец. библеотеки JS) не обрабатывать %uXXXX.
В результате:
PHP:
function unicode_urldecode_callback($m)
{
$dec = hexdec($m[1]);
$utf = '';
if ($dec < 0xFF) {$utf = chr($dec);}
elseif ($dec < 2048)
{
$utf = chr(192 + (($dec - ($dec % 64)) / 64));
$utf .= chr(128 + ($dec % 64));
}
else
{
$utf = chr(224 + (($dec - ($dec % 4096)) / 4096)).
chr(128 + ((($dec % 4096) - ($dec % 64)) / 64)).
chr(128 + ($dec % 64));
}
return $utf;
}
function unicode_urldecode_mixed($mixed)
{
if (is_array($mixed)) {return array_map('unicode_urldecode_mixed',$mixed);}
return preg_replace_callback('~%u([a-f\d]{4})~i','unicode_urldecode_callback',$mixed);
}
function _gpc_decode(&$var,$u = FALSE)
{
if (is_array($var))
{
foreach ($var as $k => $v)
{
_gpc_decode($var[$k],$u);
$nk = $u?unicode_urldecode_mixed($k):$k;
if (get_magic_quotes_gpc())
{
$nk = stripslashes($nk);
if ($nk != $k) {$var[$nk] = $var[$k]; unset($var[$k]);}
}
}
}
else
{
if ($u) {$var = unicode_urldecode_mixed($var);}
if (get_magic_quotes_gpc()) {$var = stripslashes($var);}
}
}
function _parse_str($string,&$array)
{
$string = preg_replace('~%(?!5B)(?!5D)([a-f\d]{2})~si','%u00$1',$string);
parse_str($string,$array);
}
_parse_str($_SERVER['QUERY_STRING'],$_GET);
if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {_parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$_POST);}
_gpc_decode($_GET,TRUE);
_gpc_decode($_POST,isset($GLOBALS['HTTP_RAW_POST_DATA']));
_gpc_decode($_COOKIE);
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;
Принимаются замечания/дополнения. Спасибо за внимание.
-~{}~ 18.12.06 08:24:
З.Ы. надеюсь с выходом PHP 6 код полностью потеряет актуальность: magic_quotes уже убрали, осталось лишь добавить поддержку %uXXXX.