首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP URL 參數解析四大核心方法:從 $_SERVER 到 parse_url 完整指南

     編輯:PHP 相關知識

獲取、解析 URL 參數是 Web 開發高頻需求。PHP 提供多種內置方式,各有適用場景。本文系統梳理四大核心方法、正則補充、最佳實踐與陷阱避坑。

方法一:$_SERVER 超全局數組(最原始)

// 僅查詢字符串:name=tank&sex=1
$queryString = $_SERVER['QUERY_STRING'];

// 包含路徑:/index.php?name=tank&sex=1
$requestUri = $_SERVER['REQUEST_URI'];

// 完整 URL(需自行拼協議/域名/端口)
$fullUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') 
         . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  • 優點: 無解析開銷、直接訪問原始數據
  • 缺點: 需手動解析參數、未處理 URL 解碼、多參數同名覆蓋

方法二:pathinfo() - 路徑信息分解

$url = "https://localhost/index.php?name=tank&sex=1#top";
$info = pathinfo($url);
/*
Array(
  [dirname] => https://localhost
  [basename] => index.php?name=tank&sex=1#top
  [extension] => php
  [filename] => index
)
*/
// 注意:pathinfo 為文件路徑設計,對 URL 查詢/錨點不分離
  • 適用: 純文件路徑分析、獲取副檔名、文件名
  • 不適用: 完整 URL 參數解析

方法三:parse_url() - URL 標準解析(推薦核心)

$url = "https://user:pass@localhost:8080/index.php?name=tank&sex=1#top";
$parts = parse_url($url);
/*
Array(
  [scheme] => http
  [host] => localhost
  [port] => 8080
  [user] => user
  [pass] => pass
  [path] => /index.php
  [query] => name=tank&sex=1
  [fragment] => top
)
*/
// 解析查詢字符串為關聯數組
parse_str($parts['query'], $queryParams);
/*
Array(
  [name] => tank
  [sex] => 1
)
*/
  • 優勢: 標準庫、正確處理編碼、端口、認證、IPv6、錨點
  • 注意: 不解碼查詢值,需配合 parse_str();相對路徑需補全

方法四:basename() - 獲取文件名含查詢

$url = "https://localhost/index.php?name=tank&sex=1#top";
echo basename($url); // index.php?name=tank&sex=1#top
// 同 pathinfo()['basename'],不推薦用於 URL

進階:parse_str() 完整參數解析

$query = "name=tank&sex=1&hobby[]=read&hobby[]=code&data[key]=val";
parse_str($query, $params);
/*
Array(
  [name] => tank
  [sex] => 1
  [hobby] => Array([0]=>read, [1]=>code)
  [data] => Array([key]=>val)
)
*/
// 自動處理數組語法 name[]、name[key]
// 注意:同名參數後覆蓋前,數組語法除外

正則補充:特定模式提取

$url = "https://localhost/index.php?name=tank&sex=1#top";
// 提取所有 key=value 對(含錨點)
preg_match_all('/([^?&=#]+)=([^&#]*)/', $url, $matches, PREG_SET_ORDER);
/*
[
  ['name=tank', 'name', 'tank'],
  ['sex=1', 'sex', '1'],
  // #top 不匹配(無 =)
]
*/
// 提取含錨點
preg_match_all('/([^?&=#]+)=([^&#]*)|(#\w+)/', $url, $matches);

方法對比與選型指南

需求推薦方法代碼片段
獲取原始查詢字符串$_SERVER['QUERY_STRING']$qs = $_SERVER['QUERY_STRING'];
解析完整 URL 結構parse_url()$p = parse_url($url);
查詢字符串轉關聯數組parse_str()parse_str($p['query'], $params);
獲取單個參數值$_GET['name']$name = $_GET['name'] ?? '';
構建/修改 URLhttp_build_query() + parse_url()$p['query'] = http_build_query($params);
提取特定模式參數正則preg_match_all(...)

最佳實踐封裝:UrlParser 工具類

class UrlParser {
    public static function parse(string $url): array {
        $parts = parse_url($url);
        $query = [];
        if (isset($parts['query'])) {
            parse_str($parts['query'], $query);
        }
        return array_merge($parts, ['query_params' => $query]);
    }

    public static function build(array $parts): string {
        $query = $parts['query_params'] ?? [];
        unset($parts['query_params']);
        if ($query) {
            $parts['query'] = http_build_query($query);
        }
        // 簡易重構(生產建議用 League\Uri 或 PSR-7 Uri)
        return $parts['scheme'] . '://' 
             . ($parts['user'] ?? '') . ($parts['pass'] ? ':' . $parts['pass'] : '') . (@$parts['user'] ? '@' : '')
             . $parts['host'] . ($parts['port'] ? ':' . $parts['port'] : '')
             . $parts['path'] . ($parts['query'] ? '?' . $parts['query'] : '')
             . ($parts['fragment'] ? '#' . $parts['fragment'] : '');
    }
}

// 使用
$parsed = UrlParser::parse('https://api.com/users?page=2&size=20#list');
$parsed['query_params']['page'] = 3;
$newUrl = UrlParser::build($parsed); // https://api.com/users?page=3&size=20#list

常見陷阱

  1. 雙重編碼: 已編碼字符串再次 urlencode() → %2520
  2. parse_str 全局污染: 無第二參數時註冊全局變量(已棄用/移除),必須傳數組
  3. 方括號語法衝突: filter[name]=john 會被解析為數組,需手動處理或避免
  4. 大小寫敏感: 參數名區分大小寫,ID ≠ id
  5. 相對 URL: parse_url('/path?query') 缺 scheme 會解析失敗,需補全

掌握 parse_url() + parse_str() 黃金組合,覆蓋 95% URL 解析構建需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved