短链接怎么用php还原_从基础原理到代码实现教学【详解】
技术百科
雪夜
发布时间:2026-01-01
浏览: 次 短链接还原本质是模拟浏览器跟踪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。
-
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 编码有效。
# 微信
# 浏览器
# win
# js
# curl
# html
# 编码
# red
# php
# ssl
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- php转exe用什么工具打包快_高效打包软件推荐【
- c++中如何对数组进行排序_c++数组排序算法汇总
- c++获取当前时间戳_c++ time函数使用详解
- 如何使用Golang模拟请求超时_Golang c
- Windows蓝屏错误0x0000001E怎么修复
- Win10电脑怎么设置休眠快捷键_Windows1
- Windows11怎么自定义任务栏_Windows
- 如何高效删除 NumPy 二维数组中所有元素相同的
- LINUX如何开放防火墙端口_Linux fire
- Windows服务持续崩溃怎样修复_系统服务保护机
- 为什么Go需要go mod文件_Go go mod
- Win11怎么自动隐藏任务栏_Win11全屏显示设
- 如何在Golang中捕获HTTP服务器错误_Gol
- Linux怎么实现内网穿透_Linux安装Frp客
- Ajax提交表单PHP怎么接收_处理Ajax发送的
- Windows怎样关闭开始菜单广告_Windows
- MAC如何快速搜索大文件_MAC磁盘空间分析与冗余
- Windows10无法连接到Internet_Wi
- 零基础学会Python自动化办公_高效处理Exce
- php增删改查需要哪些扩展_开启mysqli或pd
- Win11搜索栏无法输入_解决Win11开始菜单搜
- 如何在Golang中实现微服务服务拆分_Golan
- 如何将竖排文本文件转换为横排字符串
- Windows10电脑怎么连接蓝牙设备_Win10
- 如何在Mac上搭建Golang开发环境_使用Hom
- Win11怎么关闭自动调节亮度_Windows11
- Windows如何拦截腾讯视频广告_Windows
- Win11怎么更改系统语言_Win11中文语言包下
- Win10怎样设置多显示器_Win10多显示器扩展
- Win11怎么更改文件夹图标_自定义Win11文件
- c++20的std::format怎么用 比pri
- 如何使用Golang构建基础消息队列模拟_Gola
- Win11怎么查看激活状态_查询Windows 1
- Windows怎样拦截QQ浏览器广告_Window
- 如何处理“XML格式不正确”错误 常见XML we
- Windows10系统更新错误0x80070002
- Win10怎样卸载iTunes_Win10卸载iT
- Mac如何与安卓手机传文件_Mac和Android
- Win11怎么关闭OneDrive同步_Win11
- windows 10专注助手怎么关闭_window
- Windows10如何彻底关闭自动更新_Win10
- PythonDocker高级项目部署教程_多容器管
- 如何在Golang中实现自定义Benchmark_
- 如何用正则表达式精确匹配最多含一个换行符的起止片段
- 如何使用Golang搭建本地API测试环境_快速验
- Win10如何卸载微软拼音输入法 Win10只保留
- Windows10如何更改开机密码_Win10登录
- Python大型项目拆分策略_模块化解析【教程】
- Windows10如何删除恢复分区_Win10 D
- Windows怎样关闭开始菜单推荐广告_Windo

;
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;
QQ客服