短链接怎么通过php还原_新手入门级解码教程【教程】

PHP无法直接“解码”短链接,需禁用自动重定向并手动提取HTTP响应头中的Location字段;curl比file_get_contents更可控,但需处理JS跳转、反爬策略及非标准重定向等复杂情况。

短链接本身不是一种可逆编码,PHP 无法“解码”它——你真正需要的是 HTTP 301302 重定向响应里的 Location 头。

为什么 file_get_contents 读不到真实 URL

直接用 file_get_contents('https://t.co/abc123') 得到的是跳转目标页面的 HTML 内容,不是原始长链接。因为 PHP 默认跟随重定向(allow_url_fopen + follow_location 开启时),根本收不到中间的 Location 响应头。

  • 必须禁用自动跳转,手动抓取响应头
  • curlfile_get_contents 更可控
  • 部分短链服务(如 bit.ly)对未带 User-Agent 的请求会返回 403

用 curl 获取 Location 头的最小可行代码

核心是设置 CURLOPT_HEADERCURLOPT_NOBODYCURLOPT_FOLLOWLOCATIONfalse,再解析响应头。

$url = 'https://t.co/xyz789';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);        // 只要 header,不要 body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64)');

$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $header_size);
curl_close($ch);

if (preg_match('/^Location:\s*(.+)$/mi', $headers, $matches)) {
    echo trim($matches[1]);
} else {
    echo "No Location header found";
}

常见失败原因和绕过方式

不是所有短链都走标准 3xx 重定向;有些用 JS 跳转、meta refresh 或 iframe,这些 PHP 无法直接捕获。

立即学习“PHP免费学习笔记(深入)”;

  • tinyurl.com 返回 301,可用上述方法
  • is.gd 返回 301,但可能加了反爬 header 校验
  • weibo.cn/t/... 返回 200 + ,需额外解析 HTML
  • 微信内短链(url.cn/...)常返回 200 + JS 跳转 + 验证逻辑,无法纯服务端还原

别忽略 HTTP 状态码差异

301 和 302 都带 Location,但语义不同:301 是永久重定向(可缓存),302 是临时重定向(不应缓存)。实际还原时无需区分,但要注意:

  • 某些短链平台对高频请求返回 429(Too Many Requests)
  • 没设 Timeout 可能卡死,建议加 CURLOPT_TIMEOUT => 5
  • HTTPS 短链若证书异常(如自签名),需加 CURLOPT_SSL_VERIFYPEER => false(仅调试用)

真正难的不是写几行 curl,而是应对各种非标准跳转和风控策略——多数公开短链服务不承诺 API 支持,靠解析响应头只是权宜之计。