萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 解析 URL 參數完整指南:parse_url()、parse_str() 與正則進階解析

parse_url():標準 URL 解析函數

將 URL 分解為關聯陣列,支援完整 URL 或相對路徑。

基本用法

<?php
$url = "https://user:pass@example.com:8080/path/to/page?name=value&foo=bar#section";

$parts = parse_url($url);
print_r($parts);

/* 輸出:
Array
(
    [scheme] => https
    [host] => example.com
    [port] => 8080
    [user] => user
    [pass] => pass
    [path] => /path/to/page
    [query] => name=value&foo=bar
    [fragment] => section
)
*/

取得特定元件(第二參數)

$url = "https://example.com/path?query=1#frag";

echo parse_url($url, PHP_URL_SCHEME);   // https
echo parse_url($url, PHP_URL_HOST);     // example.com
echo parse_url($url, PHP_URL_PORT);     // null(無指定港口)
echo parse_url($url, PHP_URL_PATH);     // /path
echo parse_url($url, PHP_URL_QUERY);    // query=1
echo parse_url($url, PHP_URL_FRAGMENT); // frag

可用常數:`PHP_URL_SCHEME`、`PHP_URL_HOST`、`PHP_URL_PORT`、`PHP_URL_USER`、`PHP_URL_PASS`、`PHP_URL_PATH`、`PHP_URL_QUERY`、`PHP_URL_FRAGMENT`

parse_str():查詢字串解析為變數/陣列

<?php
$query = "name=John&age=30&tags[]=php&tags[]=js&tags[]=vue";

// 解析到陣列(推薦,不污染符號表)
$params = array();
parse_str($query, $params);
print_r($params);
/*
Array
(
    [name] => John
    [age] => 30
    [tags] => Array ( [0] => php, [1] => js, [2] => vue )
)
*/

// 解析到當前符號表(不推薦,安全風險)
// parse_str($query);  // 產生 $name, $age, $tags

完整 URL 解析流程:取得查詢參數陣列

function get_url_params($url) {
    $parts = parse_url($url);
    $params = array();
    if (isset($parts['query'])) {
        parse_str($parts['query'], $params);
    }
    return $params;
}

$url = "https://api.example.com/search?q=php&page=2&sort=desc&tags[]=web&tags[]=backend";
$params = get_url_params($url);
// $params = ['q'=>'php', 'page'=>'2', 'sort'=>'desc', 'tags'=>['web','backend']]

建構 URL:http_build_query()

$params = array(
    'q' => 'php tutorial',
    'page' => 2,
    'tags' => array('web', 'backend'),
    'filter' => array('type' => 'article', 'lang' => 'zh')
);

$query = http_build_query($params);
// q=php+tutorial&page=2&tags%5B0%5D=web&tags%5B1%5D=backend&filter%5Btype%5D=article&filter%5Blang%5D=zh

$url = "https://api.example.com/search?" . $query;

進階:正則表達式解析複雜 URL(舊代碼參考)

原文提供的正則解析函數,現代專案建議改用 `parse_url()` + `parse_str()`,但可作為理解 URL 結構參考:

function parseurl_regex($url) {
    $regex = "~^" .
        "(?:(?P\w+)://)?" .                    // scheme
        "(?:(?P\w+):(?P\w+)@)?" .         // user:pass@
        "(?P(?:(?P[-\w.]+)\.)?" .     // subdomain.
        "(?P[-\w]+\.(?P\w+)))" .    // domain.tld
        "(?::(?P\d+))?" .                        // :port
        "(?P[\w/]*/(?P\w+(?:\.\w+?)?)?)?" .// /path/file.ext
        "(?:\?(?P[\w=&]+))?" .                   // ?query
        "(?:#(?P\w+))?" .                      // #anchor
        "$~";
    
    preg_match($regex, $url, $matches);
    return $matches;
}

常見問題與解決方案

相對路徑 URL

$url = "/path/page?query=1";
$parts = parse_url($url);
// 只有 [path] 和 [query],無 scheme/host

無查詢字串的 URL

$url = "https://example.com/page";
$parts = parse_url($url);
// 無 [query] 鍵,需用 isset() 檢查

特殊字元編碼

$url = "https://example.com/search?q=php+教學&lang=zh-TW";
$params = get_url_params($url);
// $params['q'] = 'php 教學'(自動解碼 + 為空格)

現代替代方案:PHP 8.1+ parse_url() 改進

  • 更嚴格遵循 RFC 3986
  • 更好處理 IPv6、IDN 域名、密碼含特殊字元
  • 建議搭配 `filter_var($url, FILTER_VALIDATE_URL)` 先驗證
copyright © 萬盛學電腦網 all rights reserved