首页 > 志趣人生 > PHP相关PHP相关
php解析当前请求页面的url
在 PHP 中,“解析当前请求的 URL” 指的是获取用户正在访问的页面的完整 URL(如 https://www.example.com/path?query=1),并拆解其各个组成部分(协议、域名、路径、...
在 PHP 中,“解析当前请求的 URL” 指的是获取用户正在访问的页面的完整 URL(如 https://www.example.com/path?query=1),并拆解其各个组成部分(协议、域名、路径、参数等)。这一操作依赖于服务器环境变量($_SERVER 超全局数组)和 PHP 内置函数的结合,常用于日志记录、跳转逻辑、URL 生成等场景。
一、核心依赖:$_SERVER 超全局数组
当前请求的 URL 信息并非 PHP 直接提供,而是由 Web 服务器(如 Nginx、Apache)通过环境变量传递给 PHP,这些变量存储在 $_SERVER 数组中。解析当前 URL 的核心就是提取和组合这些变量。
以下是与 URL 解析相关的关键 $_SERVER 变量:
变量名 | 含义 | 示例值 |
HTTPS | 若请求通过 HTTPS 协议,则为 on;否则为空或未定义(用于判断协议) | on 或 空 |
SERVER_PORT | 服务器接收请求的端口号 | 80(HTTP 默认)、443(HTTPS 默认) |
HTTP_HOST | 客户端请求的域名(包含端口,若非默认),来自请求头 Host | www.example.com 或 api.example.com:8080 |
REQUEST_URI | 当前请求的路径和查询参数(不含协议、域名) | /path/to/page?name=test&age=20 |
SCRIPT_NAME | 当前执行脚本的路径(常用于获取基础路径) | /index.php |
QUERY_STRING | URL 中的查询参数字符串(? 后的部分) | name=test&age=20 |
PHP_SELF | 当前执行脚本的路径(包含相对路径) | /path/index.php |
二、构建当前完整 URL
$_SERVER 中没有直接提供 “完整 URL” 的变量,需要通过组合上述变量生成。步骤如下:
1. 确定协议(http 或 https)
通过 HTTPS 变量或 SERVER_PORT 判断:
若 $_SERVER['HTTPS'] === 'on',则为 https;
若端口是 443(HTTPS 默认端口),也可判断为 https;
其余情况为 http。
$scheme = 'http'; // 判断HTTPS if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') { $scheme = 'https'; // 或通过端口判断(兼容部分服务器配置) }elseif (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) { $scheme = 'https'; }
2. 确定域名和端口
域名:主要来自 $_SERVER['HTTP_HOST'](包含子域名,如 www.example.com);
端口:若为默认端口(http 80 / https 443),通常省略;非默认端口需显式添加。
$host = $_SERVER['HTTP_HOST'] ?? 'unknown'; // 域名(可能包含端口,如 example.com:8080) // 单独提取端口(若HTTP_HOST不含端口,则用SERVER_PORT) if (strpos($host, ':') !== false) { list($domain, $port) = explode(':', $host, 2); } else { $domain = $host; $port = $_SERVER['SERVER_PORT'] ?? 80; } // 处理默认端口(不显示) $portStr = ''; if (($scheme === 'http' && $port != 80) || ($scheme === 'https' && $port != 443)) { $portStr = ":{$port}"; } // 拼接域名+端口(如 www.example.com:8080) $hostWithPort = $domain . $portStr;
3. 拼接完整 URL
组合协议、域名 + 端口、路径 + 查询参数(REQUEST_URI):
// 路径和查询参数(如 /path?query=1) $uri = $_SERVER['REQUEST_URI'] ?? '/'; // 完整URL $currentUrl = $scheme . '://' . $hostWithPort . $uri;
三、解析当前 URL 的各个部分
通过上述步骤得到完整 URL 后,可使用 parse_url() 拆解为协议、域名、路径等部分(详见前文 parse_url() 用法),也可直接通过 $_SERVER 变量提取。
示例:完整解析当前 URL
// 1. 构建完整URL $scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST'] ?? ''; $uri = $_SERVER['REQUEST_URI'] ?? '/'; $currentUrl = $scheme . '://' . $host . $uri; // 2. 用parse_url()解析完整URL $urlParts = parse_url($currentUrl); // 3. 解析查询参数(若有) $queryParams = []; if (!empty($urlParts['query'])) { parse_str($urlParts['query'], $queryParams); } // 输出结果 echo "完整URL: {$currentUrl}\n"; echo "协议: {$urlParts['scheme']}\n"; // https echo "域名: {$urlParts['host']}\n"; // www.example.com echo "端口: " . ($urlParts['port'] ?? '默认') . "\n"; // 8080 或 默认 echo "路径: {$urlParts['path']}\n"; // /path/to/page echo "查询参数: " . print_r($queryParams, true) . "\n"; // [name => 'test', age => 20]
四、特殊场景处理
1. 反向代理环境(如 Nginx 反向代理)
若服务器在反向代理后,$_SERVER['HTTP_HOST'] 可能被代理服务器修改,需通过代理头获取真实域名:
// 优先使用代理传递的真实域名(若配置了X-Forwarded-Host) $host = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? ($_SERVER['HTTP_HOST'] ?? '');
2. 路径中的脚本名(如 index.php)
若 URL 通过 index.php 转发(如框架路由),REQUEST_URI 包含完整路径,而 SCRIPT_NAME 仅指脚本本身:
// 示例:URL为 https://example.com/index.php/user/list?page=1 echo $_SERVER['REQUEST_URI']; // /index.php/user/list?page=1 echo $_SERVER['SCRIPT_NAME']; // /index.php
3. 处理 URL 编码字符
URL 中的特殊字符(如空格、中文)会被编码(如空格→%20),需用 urldecode() 解码:
$encodedPath = '/search?keyword=%E5%8F%B0%E5%8C%E8%99%E8%8B%B1%E6%96%87'; $decodedPath = urldecode($encodedPath); // 结果:/search?keyword=台湾英文
五、总结
解析当前请求的 URL 的核心流程是:
利用 $_SERVER 变量提取协议、域名、端口、路径等基础信息;
组合这些信息生成完整 URL;
用 parse_url() 和 parse_str() 拆解为结构化数据(协议、域名、参数等)。
需注意环境差异(如反向代理)和特殊字符编码,确保解析结果准确。
0
0
快快抢占沙发吧!