PHP版获取重定向后的地址(代码)
本文介绍如何使用PHP的fsockopen函数发送HTTP请求,以获取经过重定向后的最终目标URL地址。
环境准备
本方法基于标准的PHP运行环境,依赖核心网络函数fsockopen。确保服务器允许出站网络连接且未禁用相关函数。
第1步:定义URL解析类
创建一个名为RedirectUrl的类来封装重定向解析逻辑。该类需要维护一个属性存储初始URL。
class RedirectUrl {
private $url;
public function __construct($url) {
$this->url = $url;
}
}
第2步:实现单次重定向获取方法
在类中添加私有方法get_redirect_url,负责向目标服务器发起HEAD请求并提取首个Location头。该方法包含参数校验及Socket连接部分。
核心逻辑说明:
- 使用parse_url分解URL结构。
- 调用fsockopen建立TCP连接。
- 构造符合HTTP/1.1规范的HEAD请求报文。
- 读取响应数据并使用正则表达式匹配Location字段。
private function get_redirect_url($url) {
$url_parts = @parse_url($url);
if (!$url_parts || !isset($url_parts['host'])) return false;
if (!isset($url_parts['path'])) $url_parts['path'] = '/';
$sock = fsockopen($url_parts['host'], (isset($url_parts['port']) ? (int)$url_parts['port'] : 80), $errno, $errstr, 30);
if (!$sock) return false;
$request = "HEAD " . $url_parts['path'] . (isset($url_parts['query']) ? '?' . $url_parts['query'] : '') . " HTTP/1.1\r\n";
$request .= 'Host: ' . $url_parts['host'] . "\r\n";
$request .= "Connection: Close\r\n\r\n";
fwrite($sock, $request);
$response = '';
while (!feof($sock)) $response .= fread($sock, 8192);
fclose($sock);
if (preg_match('/^Location: (.+?)$/m', $response, $matches)) {
return trim($matches[1]);
} else {
return false;
}
}
第3步:构建链式循环获取所有重定向
添加get_all_redirects方法以支持多跳重定向的处理。此方法将持续追踪直到不存在后续的Location头。
private function get_all_redirects($url) {
$redirects = array();
while ($newurl = $this->get_redirect_url($url)) {
if (in_array($newurl, $redirects)) break;
$redirects[] = $newurl;
$url = $newurl;
}
return $redirects;
}
第4步:获取最终URL
公开get_final_url方法,从完整的重定向链中提取最后一项作为实际页面地址。若无可提取内容则返回原URL。
public function get_final_url() {
$redirects = $this->get_all_redirects($this->url);
if (count($redirects) > 0) {
return array_pop($redirects);
} else {
return $this->url;
}
}
第5步:调用实例化与验证
将上述类整合入具体业务逻辑。通常直接实例化对象并调用其get_final_url即可得到重定向结果。
$url = 'http://example.com/source_url';
$obj = new RedirectUrl($url);
echo $obj->get_final_url();
风险与注意事项
- fsockopen可能在受限环境中被禁用,请确认当前服务器配置。
- 对于HTTPS协议的重定向,单纯文本匹配Location可能不够准确,涉及SSL握手需额外处理或使用cURL库。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









