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

短链接还原不能只靠 urldecode,它只解码 URL 编码字符,不发起 HTTP 请求获取跳转目标。真正还原短链接,得用 PHP 发起请求跟踪重定向。
短链接还原的本质是跟踪 301/302 跳转
像 https://t.co/abc123 或 https://dwz.cn/xyz 这类短链,服务端实际返回的是 Location: https://real-url.com/... 响应头。PHP 必须发送 HEAD 或 GET 请求,并开启重定向跟随,才能拿到最终 URL。
-
urldecode()只处理类似%E4%BD%A0%E5%A5%BD这种编码,对短链本身无作用 - 短链地址本身通常已是合法 URL 字符(无 % 编码),
urldecode()调用后基本不变 - 必须用
curl或file_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)。
立即学习“PHP免费学习笔记(深入)”;
$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 被错误解成 /)。











