短链接还原内存溢出主因是未优化cURL配置;应设CURLOPT_NOBODY=true、CURLOPT_MAXREDIRS=10,并调高memory_limit至512M,优先用ini_set()或php.ini修改。

短链接还原时 PHP 报 Allowed memory size exhausted
短链接还原本质是多次 HTTP 重定向追踪(比如从 https://t.co/abc → https://bit.ly/xyz → 最终目标 URL),PHP 默认用 curl 或 file_get_contents 实现时,若中间跳转多、响应体大、或开启了冗余的 CURLOPT_HEADER 或 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true) 但未限制跳转次数,就容易吃光默认内存(通常 128M 或更少)。
memory_limit 设置位置不生效?优先级和写法要对
PHP 内存限制受多个配置层级影响,顺序为:ini_set() > .htaccess(仅 Apache + mod_php)> php.ini > user.ini(PHP-FPM 环境常用)。直接改 php.ini 最稳妥,但线上环境常受限;用 ini_set('memory_limit', '512M') 必须放在脚本最开头,且不能高于 php.ini 中 memory_limit 的硬上限(如 ini 中设为 128M,ini_set 设 512M 也无效)。
- 查当前生效值:
echo ini_get('memory_limit'); - 临时提限(脚本开头):
ini_set('memory_limit', '512M'); - 永久提限(推荐):编辑
php.ini,改行memory_limit = 512M,然后重启 PHP 服务(systemctl restart php-fpm或service apache2 restart)
更轻量的还原方式:禁用 body、限制跳转、用 HEAD 请求
短链接还原真正需要的只是最终的 Location 响应头,不是完整页面内容。用 HEAD 方法 + 关闭 body 缓存,可大幅降低内存占用:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $short_url); curl_setopt($ch, CURLOPT_NOBODY, true); // 只取 header curl_setopt($ch, CURLOPT_HEADER, false); // 不返回 header 到输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 捕获结果 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 允许跳转 curl_setopt($ch, CURLOPT_MAXREDIRS, 10); // 强制限制最多 10 次跳转 curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 防卡死 $resp = curl_exec($ch); $redirect_url = curl_getinfo($ch, CURLINFO_REDIRECT_URL); curl_close($ch);
注意:CURLINFO_REDIRECT_URL 返回的是最后一次跳转后的 URL(即最终目标),前提是所有跳转都用了 301/302 和标准 Location 头;如果某次跳转是 JS 跳转或 meta refresh,这个方法会失效——那就得换 DOM 解析,但那是另一类内存问题了。
立即学习“PHP免费学习笔记(深入)”;
PHP 8.0+ 的 curl_share_init() 不适用短链还原
有人查文档看到 curl_share_init() 可复用连接、省资源,但短链接还原是串行跳转(A→B→C),每次请求 URL 不同,无法共享 cookie 或 DNS 缓存,强行套用反而增加逻辑复杂度。真实瓶颈在单次响应体大小和跳转深度,不是连接初始化开销。
别迷信“高级 API”,先确认是不是真需要——90% 的短链还原场景,调对 CURLOPT_NOBODY 和 CURLOPT_MAXREDIRS 就够了。内存不够,往往是因为把整个跳转链的 HTML 全读进内存再正则提取 Location,而不是让 cURL 自己处理重定向。











