短链接还原本质是模拟浏览器跟踪HTTP重定向,而非解密;需手动处理301/302等跳转响应,提取Location头并拼接相对路径,限制跳转次数,适配不同服务商的UA、Referer及HTML/JS跳转策略。

短链接还原不是“解密”,而是通过 HTTP 重定向链路获取最终目标 URL——PHP 本身不存储原始链接,它只是服务端响应重定向请求的一环。关键在理解 Location 响应头和跳转逻辑,而非“反向破解”。
短链接还原的本质是模拟浏览器发起 GET 请求并跟踪 301/302 跳转
用户点击短链接(如 https://t.co/abc123)时,浏览器收到 301 Moved Permanently 或 302 Found 响应,自动用 Location 头里的值发起下一次请求。PHP 要做的,就是复现这个过程。
- 不能靠解析短链接字符串(如 base64、自增 ID 解码)来“还原”,除非你完全掌控该短链服务的生成逻辑
- 真实场景中,
t.co、bit.ly、dwz.cn等均不公开跳转映射表,唯一可靠路径是走 HTTP 跳转 - 需手动控制
max_redirects,避免无限跳转(如 A→B→A 循环)或恶意跳转链
用 cURL 跟踪跳转:设置 CURLOPT_FOLLOWLOCATION 不够用
直接开 CURLOPT_FOLLOWLOCATION 会让 cURL 自动跳转到底,但你拿不到中间每一步的 Location,也看不到最终 URL 是哪次跳转给出的——这对调试、防钓鱼、统计跳转深度都很关键。
- 必须关闭自动跳转:
CURLOPT_FOLLOWLOCATION => false - 手动检查响应码:
in_array($httpCode, [301, 302, 303, 307, 308]) - 从
curl_getinfo($ch, CURLINFO_REDIRECT_URL)或响应头中提取Location值(注意:某些服务返回相对路径,需拼接) - 每次跳转前更新
curl_setopt($ch, CURLOPT_URL, $nextUrl)
$url = 'https://t.co/xYzAbC';
$maxRedirects = 5;
$redirects = 0;
while ($redirects < $maxRedirects) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true); // 只取 header,更快
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-cURL');
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$redirectUrl = curl_getinfo($ch, CURLINFO_REDIRECT_URL);
curl_close($ch);
if (!in_array($httpCode, [301, 302, 303, 307, 308])) {
break; // 不再跳转,当前 $url 即最终地址(或出错)
}
if (!$redirectUrl) {
// 尝试从响应头里手动提取 Location
$headers = substr($response, 0, curl_getinfo($ch, CURLINFO_HEADER_SIZE));
if (preg_match('/^Location:\s*(.+)$/mi', $headers, $matches)) {
$redirectUrl = trim($matches[1]);
}
}
if (!$redirectUrl) break;
// 处理相对路径(如 /path?x=1)
if (parse_url($redirectUrl, PHP_URL_SCHEME) === null) {
$url = rtrim($url, '/') . '/' . ltrim($redirectUrl, '/');
} else {
$url = $redirectUrl;
}
$redirects++;
}
echo "Final URL: " . $url;
常见失败原因和绕过技巧
很多短链服务会做 UA 检查、Referer 限制、甚至 JS 重定向(cURL 拿不到),导致 Location 头为空或返回 403/406。
立即学习“PHP免费学习笔记(深入)”;
-
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 ...')必须设,否则t.co直接返回 403 - 有些服务(如微信短链
weixin110.com)返回 302 + HTML meta refresh,需额外解析 body 中的 - 极少数用 JS 跳转(
window.location.href),PHP 无法执行 JS,此时只能放弃或换 Puppeteer/Playwright - 响应头中的
Location可能带空格或换行,务必trim()
真正稳定的还原,永远依赖服务端是否愿意暴露跳转目标——没有通用“解密算法”,只有适配不同服务商响应模式的耐心。别信“一行代码还原所有短链”的说法,那大概率只对自家数据库 ID 编码有效。











