短链接还原php用什么函数_详细讲解urldecode等函数用法【介绍】

短链接还原必须通过HTTP请求跟踪重定向,不能仅用urldecode;应使用cURL设置CURLOPT_FOLLOWLOCATION和CURLOPT_NOBODY获取CURLINFO_EFFECTIVE_URL,或用file_get_contents配合stream_context(能力较弱)。

短链接还原不能只靠 urldecode,它只解码 URL 编码字符,不发起 HTTP 请求获取跳转目标。真正还原短链接,得用 PHP 发起请求跟踪重定向。

短链接还原的本质是跟踪 301/302 跳转

https://t.co/abc123https://dwz.cn/xyz 这类短链,服务端实际返回的是 Location: https://real-url.com/... 响应头。PHP 必须发送 HEAD 或 GET 请求,并开启重定向跟随,才能拿到最终 URL。

  • urldecode() 只处理类似 %E4%BD%A0%E5%A5%BD 这种编码,对短链本身无作用
  • 短链地址本身通常已是合法 URL 字符(无 % 编码),urldecode() 调用后基本不变
  • 必须用 curlfile_get_contents() 配合流上下文选项来跟踪跳转

用 curl 获取真实 URL(推荐)

curl 支持细粒度控制重定向行为,是最可靠的方式。关键是设置 CURLOPT_FOLLOWLOCATION 和禁用 body 以提升速度。

function resolveShortUrl($shortUrl) {
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $shortUrl,
        CURLOPT_NOBODY => true,           // 只取 header,不下载 body
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,   // 自动跟随 Location
        CURLOPT_MAXREDIRS => 5,           // 防止环形跳转
        CURLOPT_TIMEOUT => 10,
        CURLOPT_SSL_VERIFYPEER => false,  // 生产环境建议保持 true 并配置 ca bundle
        CURLOPT_HEADER => true,           // 获取响应头,用于调试
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
    
    curl_close($ch);
    
    if ($httpCode >= 400 || !$finalUrl) {
        return null;
    }
    
    return $finalUrl;
}
  • 务必设 CURLOPT_NOBODY => true:多数短链服务只靠 header 返回跳转,省带宽又快
  • CURLINFO_EFFECTIVE_URL 是最终到达的 URL,比手动解析 Location 头更稳妥(尤其多级跳转时)
  • 不要依赖 CURLOPT_HEADERFUNCTION 自己解析 Location,curl 内部重定向逻辑已处理 301/302/307/308 等全部情况

file_get_contents + stream_context 的替代方案

如果服务器禁用了 curl,可用 file_get_contents 配合自定义 context,但能力较弱,不支持自动多级跳转(PHP 7.4+ 才支持 max_redirects)。

$context = stream_context_create([
    'http' => [
        'method' => 'HEAD',
        'max_redirects' => 5,
        'timeout' => 10,
        'ignore_errors' => true,
    ]
]);
$realUrl = file_get_contents($shortUrl, false, $context);
// 注意:file_get_contents 不直接暴露最终 URL,需读取 context 中的 'redirect' 信息
// 或改用 get_headers() + 手动循环,但易出错
  • get_headers($url, 1) 可读取响应头,但需自己循环处理 Location,遇到 307/308 或跨域跳转容易失败
  • PHP 8.0+ 的 stream_context_set_params() 仍无法在运行时动态获取最终 URL,不如 curl 直观
  • 该方式在 open_basedir 或 allow_url_fopen = Off 时直接失效

urldecode、rawurldecode、htmlspecialchars_decode 的常见误用场景

这些函数和短链还原无关,但常被误认为“能解开短链”。它们只做字符串转义还原:

  • urldecode("hello%20world") → "hello world":还原 application/x-www-form-urlencoded 编码
  • rawurldecode("hello%20world") → "hello world":同上,但不把 + 当空格(更严格)
  • htmlspecialchars_decode("zuojiankuohaophpcnscriptyoujiankuohaophpcn") → ":仅反转义 HTML 实体,和 URL 无关
  • 若短链参数里带编码(如 https://t.co/abc?ref=%E4%BD%A0),才需对 $_GET['ref']urldecode()

别试图对整个短链 URL 调用 urldecode() —— 它大概率原样返回,还可能破坏合法的 % 字符(比如图片 URL 中的 %2F 被错误解成 /)。