PHP实现短域名展开为实际URL的函数方法

落日邮差
落日邮差
发布时间:2026-10-15| 6人浏览过
原创

在Web开发或数据采集场景中,经常遇到需要经过多次跳转的短域名链接。本文将展示如何使用原生PHP函数提取短链接背后的真实目标地址,核心逻辑基于HTTP协议的302重定向特性,通过解析响应头中的Location字段完成转换。

实现原理与准备

大多数短域名服务(如t.cn、sinaurl.cn)在用户访问时,服务器会返回一个 302 Found 状态码,并在 HTTP 响应头中包含一个 Location 字段,指向最终的长链接。我们的目标是模拟浏览器发起请求,捕获这一头部信息并提取目标地址。

所需环境:
- PHP 环境
- 确保服务器的 allow_url_fopen 配置为开启状态,以便使用 file_get_contents 或相关网络函数

第1步:编写短域名转换函数

该函数主要包含两个部分:主逻辑用于获取和解析响应头,辅助函数用于判断字符串是否以特定前缀开头。我们将完整的逻辑封装在一个可复用的代码块中。

目的:定义一个名为 unshorten 的函数,输入短链接,输出真实链接。

操作:

  1. 初始化参数:接收待解析的URL字符串,去除首尾空格。
  2. 获取响应头:调用 get_headers() 函数。注意,此函数默认可能需要先访问一次URL才能看到重定向后的头部。如果直接获取不到重定向前头部,通常需要先设置上下文或使用更底层的Socket连接。但在简单场景下,get_headers($url) 通常会触发重定向并返回最终状态的头部信息,或者我们需要显式跟随重定向。

以下是优化后的完整代码示例,修正了原文本中可能存在的缩进混乱,并明确了逻辑流程:

<?php
// 示例短链接
$url = "http://sinaurl.cn/hbdsU5";
echo unshorten($url);

/**
 * 将短域名转换为实际域名函数
 */
function unshorten($url) {
    $url = trim($url);
    
    // 强制PHP跟随重定向获取最终的Header信息
    // get_headers 默认可能不跟随所有重定向,取决于PHP版本和环境配置
    // 更稳健的方式是使用 stream_context 或直接请求
    $headers = get_headers($url, 1);
    
    if (!$headers || !is_array($headers)) {
        return false; // 无法获取头部信息
    }
    
    // 寻找 Location 头
    // 注意:在某些PHP环境下,get_headers 只返回最后一次重定向的状态
    // 为了兼容性好,我们遍历所有可能的 header 条目
    $location = null;
    
    foreach ($headers as $head) {
        if (is_string($head)) {
            if (strpos($head, 'Location:') !== false || strpos($head, 'location:') !== false) {
                list($headerName, $headerValue) = explode(':', $head, 2);
                $location = trim($headerValue);
                break;
            }
        } elseif (is_array($head)) {
            // 处理重复 Header 的情况
             foreach ($head as $h) {
                 if (is_string($h) && strpos($h, 'Location') !== false) {
                     list($headerName, $headerValue) = explode(':', $h, 2);
                     $location = trim($headerValue);
                 }
             }
        }
    }
    
    // 如果通过标准方式未找到,且URL发生了改变(某些服务器行为),可尝试以下备用逻辑
    // 但大多数情况下,get_headers 配合默认行为即可
    
    // 如果没找到 location,返回原URL或false
    if ($location) {
        return $location;
    }
    
    // 备用方案:检查 HTTP/1.1 302 状态并手动解析字符串
    // 这对应于原文的逻辑风格,更具通用性针对非数组返回情况
    $rawHeaders = get_headers($url, 0);
    if (is_array($rawHeaders)) {
        $short = false;
        foreach($rawHeaders as $headStr) {
            $headStr = trim($headStr);
            if(str_starts_with($headStr, "HTTP/")) {
                if(strpos($headStr, "302") !== false) $short = true;
                else $short = false;
            }
            if($short && str_starts_with(strtolower($headStr), "location: ")) {
                $location = substr($headStr, strlen("location: "));
                break;
            }
        }
        if($location) return $location;
    }
    
    return $url; // 如果没有跳转,返回原地址
}

// 兼容旧版PHP的 startwith 替代,PHP8+支持 str_starts_with
if (!function_exists('str_starts_with')) {
    function str_starts_with($haystack, $needle) {
        return strncmp($haystack, $needle, strlen($needle)) === 0;
    }
}
?>

第2步:验证与注意事项

入口:本地PHP运行环境或Web服务器。
关键参数:$url 必须包含协议头(http:// 或 https://)。缺少协议可能导致解析失败。
完成状态:脚本运行后,控制台输出或页面显示为目标长链接。

排错指南

  • 返回原URL而非真实地址:可能因为目标服务器禁用了自动重定向,或PHP环境中 allow_url_fopen 被关闭。请检查 php.ini 配置。
  • SSL证书错误:如果短链接指向HTTPS站点而系统证书缺失,可能会报错。可在运行时添加SSL验证忽略上下文,或更新系统根证书。
  • 异步加载问题:部分现代短链接采用JavaScript跳转,此时服务器不会立即返回Location头。上述代码仅适用于HTTP重定向类短链接。对于JS跳转,需借助CURL模拟浏览器或Selenium等工具解析。

以上就是PHP将短域名展开为实际网址的详细内容,更多关于PHP网络请求处理的技术资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。