首页 > 解决方案 > 我正在获取未被 $_GET[tag] 解码的编码 URL,例如 %5Cu003d 将解码“=”

问题描述

我得到一些用户请求带有编码 URL 的页面,这些 URL 只是没有通过 $_GET[tag] 解码。

在我看来,最严重的罪犯是 %5Cu003d,但还有其他人。在这个例子中 page.php?tag%5Cu003d44 应该是 page.php?tag=44 因为 %5C 是 / 所以 /u003D 是 unicode 003D 或 "="

我不知道哪个网站对这个 URL 进行了编码,但我试图在不手动解码的情况下为人们提供他们想要的东西。是否有一些开关或方法可以使 $_GET 工作?应该不会吧?

我尝试在关于 SO 的另一次讨论中发送此标头,但没有帮助。header ('内容类型: text/html; charset=utf-8');

编辑*****************************

以下是更多错误 URL 的示例:

page.php?lat=25.79&amp%3Blon=-80.16
page.php?lat=41.46u0026lon%3D-82.71
page.php?lat%5Cu003d30.31%5Cu0026lon%5Cu003d-89.33
page.php?lat=28.94-89.4&lon

标签: phpunicodeget

解决方案


如果这是我的项目,我可能不会尊重这些网址——即使利益相关者问得很好。这确实是一团糟,数据很可能在解码过程中被破坏。...但是如果您想尝试一下,可以从以下内容开始:

代码:(演示

// this is hack until you can manage to resolve the encoding issue in a more professional manner
// use $_SERVER['QUERY_STRING'] to extract the query string from the url

$queryStrings = [
    'lat=25.79&amp%3Blon=-80.16',
    'lat=41.46u0026lon%3D-82.71',
    'lat%5Cu003d30.31%5Cu0026lon%5Cu003d-89.33',
    'lat=28.94-89.4&lon',
    'tag%5Cu003d44'
];

foreach ($queryStrings as $queryString) {

    // replace unicode-like substrings
    $queryString = preg_replace_callback('/u([\da-f]{4})/i', function ($match) {
        return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
    }, urldecode($queryString));
    // courtesy of Gumbo: https://stackoverflow.com/a/2934602/2943403
    
    // replace ampersands and remove backslashes
    $queryString = strtr($queryString, ['&' => '&', '\\' => '']);
    
    // parse the decoded query string back into the GET superglobal so that regular processing can resume
    parse_str($queryString, $_GET);
    var_export($_GET);
    echo "\n";
}

输出:

array (
  'lat' => '25.79',
  'lon' => '-80.16',
)
array (
  'lat' => '41.46',
  'lon' => '-82.71',
)
array (
  'lat' => '30.31',
  'lon' => '-89.33',
)
array (
  'lat' => '28.94-89.4',    // <-- I guess you'll need to massage this into the correct shape too
  'lon' => '',
)
array (
  'tag' => '44',
)

推荐阅读