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

PHP 解析 URL 並提取參數的完整指南:parse_url 與自定義函數實戰

     編輯:PHP 相關知識

場景痛點

日常開發中頻繁遇到需從完整 URL 中提取域名、路徑、查詢參數等結構化信息的需求:OAuth 回調處理、API 簽名驗證、URL 重寫路由分發、爬蟲去重判斷等。PHP 內置 parse_url() 與 parse_str() 可覆蓋 90% 場景,但理解其邊界行為並封裝通用工具函數,能大幅提升代碼健壯性。

核心函數速查

函數作用返回值類型
parse_url($url, $component = -1)解析 URL 為關聯數組array / string / false
parse_str($string, &$array)將查詢字符串解析為變量void (引用賦值)
http_build_query($data)數組構建查詢字符串string

實戰代碼演示

<?php
$url = 'https://api.example.com/v1/users?status=active&page=2&limit=20&sort=desc';

// 1. 解析 URL 主體結構
$parts = parse_url($url);
/*
輸出結構:
array(
  'scheme' => 'https',
  'host'   => 'api.example.com',
  'path'   => '/v1/users',
  'query'  => 'status=active&page=2&limit=20&sort=desc'
)
*/

// 2. 將 query 字符串轉為關聯數組(推薦用 parse_str)
$params = [];
parse_str($parts['query'], $params);
/*
$params = [
  'status' => 'active',
  'page'   => '2',
  'limit'  => '20',
  'sort'   => 'desc'
]
*/

// 3. 修改參數後重新構建 URL
$params['page'] = 3;          // 翻頁
$params['debug'] = 'true';    // 新增調試參數
$newQuery = http_build_query($params);
$newUrl = $parts['scheme'].'://'.$parts['host'].$parts['path'].'?'.$newQuery;

// 結果:https://api.example.com/v1/users?status=active&page=3&limit=20&sort=desc&debug=true
echo $newUrl;

自定義工具函數封裝(兼容舊項目/特殊編碼場景)

<?php
/**
 * 將查詢字符串安全解析為關聯數組
 * @param string $query  不含 ? 的 query 部分
 * @return array
 */
function convertUrlQuery(string $query): array {
    $params = [];
    // 支援 & 和 & 兩種分隔符
    $pairs = preg_split('/[&;]/', $query);
    foreach ($pairs as $pair) {
        if ($pair === '') continue;
        // 僅在第一個 = 分割,值中可能包含 =
        [$key, $value] = array_pad(explode('=', $pair, 2), 2, '');
        $params[urldecode($key)] = urldecode($value);
    }
    return $params;
}

/**
 * 關聯數組編碼為標準查詢字符串
 * @param array $params
 * @param int $enc_type  PHP_QUERY_RFC1738 (空格編碼為 +) 或 PHP_QUERY_RFC3986 (空格編碼為 %20)
 * @return string
 */
function getUrlQuery(array $params, int $enc_type = PHP_QUERY_RFC3986): string {
    return http_build_query($params, '', '&', $enc_type);
}

// 測試
$raw = 'name=John+Doe&city=Shanghai&tag=php%20code';
$arr = convertUrlQuery($raw);
// ['name'=>'John Doe','city'=>'Shanghai','tag'=>'php code']
$rebuilt = getUrlQuery($arr);
// name=John+Doe&city=Shanghai&tag=php+code (RFC1738) 或 %20 (RFC3986)

常見坑點與最佳實踐

  1. 多值參數處理:?ids[]=1&ids[]=2 用 parse_str 直接得到 $ids = [1,2];手寫解析需自行識別 [] 後綴。
  2. URL 編碼一致性:輸出 HTML 頁面時用 htmlspecialchars() 雙重編碼防 XSS;API 簽名時嚴格按 RFC3986 編碼(http_build_query($arr, '', '&', PHP_QUERY_RFC3986))。
  3. 相對路徑補全:parse_url('/path?k=v') 返回 ['path'=>'/path','query'=>'k=v'],無 scheme/host,拼接時需判斷補全。
  4. 異常輸入防禦:parse_url 遇到非法 URL 返回 false,務必先判斷再訪問下標。

一鍵複製的通用 Helper 類

<?php
class UrlParser {
    public static function parse(string $url): array {
        $parts = parse_url($url);
        if ($parts === false) throw new InvalidArgumentException('Invalid URL');
        $parts['query_params'] = isset($parts['query']) ? self::parseQuery($parts['query']) : [];
        return $parts;
    }

    public static function parseQuery(string $query): array {
        $params = [];
        parse_str($query, $params);
        return $params;
    }

    public static function build(string $baseUrl, array $extraParams = []): string {
        $parts = self::parse($baseUrl);
        $parts['query_params'] = array_merge($parts['query_params'], $extraParams);
        $query = http_build_query($parts['query_params'], '', '&', PHP_QUERY_RFC3986);
        return ($parts['scheme']??'').'://'.($parts['host']??'').($parts['path']??'').($query?'?'.$query:'');
    }
}

// 用法
$newUrl = UrlParser::build('https://api.example.com/v1/users?status=active', ['page'=>3, 'debug'=>true]);
💡 總結:日常開發首選 parse_url() + parse_str() + http_build_query() 內置三件套,性能最優且處理邊界情況最完善;特殊編碼需求或舊系統兼容時再引入自定義封裝。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved