首页 > 志趣人生 > 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 的核心流程是:
  1. 利用 $_SERVER 变量提取协议、域名、端口、路径等基础信息;

  1. 组合这些信息生成完整 URL;

  1. 用 parse_url() 和 parse_str() 拆解为结构化数据(协议、域名、参数等)。

需注意环境差异(如反向代理)和特殊字符编码,确保解析结果准确。


0
0

文章导航

共有 0 条热心评论

快快抢占沙发吧!

发表评论

安全验证
Top