

新闻资讯
技术学院短链接还原本质是模拟浏览器跟踪HTTP重定向,而非解密;需手动处理301/302等跳转响应,提取Location头并拼接相对路径,限制跳转次数,适配不同服务商的UA、Referer及HTML/JS跳转策略。
短链接还原不是“解密”,而是通过 HTTP 重定向链路获取最终目标 URL——PHP 本身不存储原始链接,它只是服务端响应重定向请求的一环。关键在理解 Location 响应头和跳转逻辑,而非“反向破解”。
用户点击短链接(如 https://t.co/abc123)时,浏览器收到 301 Moved Permanently 或 302 Found 响应,自动用 Location 头里的值发起下一次请求。PHP 要做的,就是复现这个过程。
t.co、bit.ly、dwz.cn 等均不公开跳转映射表,唯一可靠路径是走 HTTP 跳转max_redirects,避免无限跳转(如 A→B→A 循环)或恶意跳转链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。
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 ...') 必须设,否则 t.co 直接返回 403weixin110.com)返回 302 + HTML meta refresh,需额外解析 body 中的
window.location.href),PHP 无法执行 JS,此时只能放弃或换 Puppeteer/PlaywrightLocation 可能带空格或换行,务必 trim()
真正稳定的还原,永远依赖服务端是否愿意暴露跳转目标——没有通用“解密算法”,只有适配不同服务商响应模式的耐心。别信“一行代码还原所有短链”的说法,那大概率只对自家数据库 ID 编码有效。