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

PHP URL 處理函數大全:編碼、解碼、解析、構建一網打盡

     編輯:PHP 相關知識

URL 處理是 Web 開發的高頻需求。PHP 提供了一組完整的原生函數覆蓋編碼、解碼、解析、構建、元數據提取等場景。本文系統整理這些函數的用法、差異與最佳實踐。

編碼與解碼函數對比

1. Base64 編碼(非 URL 專用,但常用於傳遞二進制數據)

<?php
$str = 'This is an encoded string';
$encoded = base64_encode($str);  // VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==
$decoded = base64_decode($encoded);  // This is an encoded string

// URL 安全版 Base64(替換 + / =)
function base64url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function base64url_decode($data) {
    return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}

2. URL 編碼四大函數核心差異

<?php
$url = 'https://www.example.com/search?q=中文 test';

// urlencode:空格編碼為 +,符合 application/x-www-form-urlencoded 標準
echo urlencode($url);  
// http%3A%2F%2Fwww.example.com%2Fsearch%3Fq%3D%E4%B8%AD%E6%96%87+test

// rawurlencode:空格編碼為 %20,符合 RFC 3986,適用於 URL 路徑部分
echo rawurlencode($url);  
// http%3A%2F%2Fwww.example.com%2Fsearch%3Fq%3D%E4%B8%AD%E6%96%87%20test

// 解碼對應
urldecode($encoded);      // 對應 urlencode
rawurldecode($encoded);   // 對應 rawurlencode

選擇原則:

  • 查詢字符串參數值 → urlencode/urldecode
  • URL 路徑、Fragment、自定義 Scheme → rawurlencode/rawurldecode
  • 構建完整 URL 時 → 路徑用 rawurlencode,Query 參數用 urlencode

URL 解析與構建

1. parse_url:分解 URL 組件

<?php
$url = 'https://user:pass@example.com:8080/path/to/page?query=string#fragment';
print_r(parse_url($url));
/*
Array
(
    [scheme] => http
    [host] => example.com
    [user] => user
    [pass] => pass
    [port] => 8080
    [path] => /path/to/page
    [query] => query=string
    [fragment] => fragment
)
*/

注意: 不驗證 URL 合法性,不完整 URL 也會盡力解析。PHP 8.1+ 對無 Scheme 的 URL 解析行為有變化,建議始終提供完整 URL。

2. http_build_query:構建查詢字符串

<?php
$data = [
    'c' => 'blog',
    'a' => 'show',
    'id' => 10,
    'tags' => ['php', 'url', 'encoding'],
    'filter' => ['status' => 1, 'type' => 'article']
];

// 基礎用法
echo http_build_query($data);
// c=blog&a=show&id=10&tags%5B0%5D=php&tags%5B1%5D=url&tags%5B2%5D=encoding&filter%5Bstatus%5D=1&filter%5Btype%5D=article

// 數字索引鍵名加前綴
echo http_build_query(['hello', 'world'], 'item_');
// item_0=hello&item_1=world

// 指定分隔符(PHP 5.4+)
echo http_build_query($data, '', '&');  // XML/HTML 安全

3. parse_str:解析查詢字符串為變量/數組

<?php
$query = 'name=John&age=30&hobbies[]=reading&hobbies[]=coding';

// 解析到數組(推薦)
$arr = [];
parse_str($query, $arr);
print_r($arr);
/*
Array
(
    [name] => John
    [age] => 30
    [hobbies] => Array ( [0] => reading [1] => coding )
)
*/

// 直接解析到當前符號表(不推薦,污染命名空間)
parse_str($query);
echo $name; // John

HTTP 頭與元數據提取

1. get_headers:獲取響應頭

<?php
// 獲取所有頭(數字索引)
$headers = get_headers('https://www.example.com');
/*
Array
(
    [0] => HTTP/1.1 200 OK
    [1] => Server: nginx
    [2] => Date: Mon, 01 Jan 2024 00:00:00 GMT
    ...
)
*/

// 關聯數組格式(PHP 5.4+)
$headers = get_headers('https://www.example.com', 1);
/*
Array
(
    [0] => HTTP/1.1 200 OK
    [Server] => nginx
    [Date] => Mon, 01 Jan 2024 00:00:00 GMT
    [Set-Cookie] => Array ( [0] => ... [1] => ... )
)
*/

// 僅獲取頭部,不下載 Body(流式上下文)
$ctx = stream_context_create(['http' => ['method' => 'HEAD']]);
$headers = get_headers('https://www.example.com', 1, $ctx);

2. get_meta_tags:提取頁面 Meta 標簽

<?php
$meta = get_meta_tags('https://www.example.com');
/*
Array
(
    [keywords] => PHP, 教程, 開發
    [description] => 專業的 PHP 技術博客
    [generator] => WordPress 6.4
    [viewport] => width=device-width, initial-scale=1
)
*/

// 注意:只能獲取  和 ,無法獲取 property (og:*) 或 charset

實戰場景最佳實踐

場景一:API 請求 URL 構建

function buildApiUrl(string $baseUrl, string $endpoint, array $params = []): string {
    $url = rtrim($baseUrl, '/') . '/' . ltrim($endpoint, '/');
    if (!empty($params)) {
        $url .= '?' . http_build_query($params);
    }
    return $url;
}

// 使用
$apiUrl = buildApiUrl('https://api.example.com', '/v1/users', [
    'page' => 1,
    'per_page' => 20,
    'filter' => ['active' => true, 'role' => 'admin']
]);

場景二:安全重定向(防開放重定向攻擊)

function safeRedirect(string $targetUrl, array $allowedHosts = []): void {
    $parsed = parse_url($targetUrl);
    if (!$parsed || !isset($parsed['host'])) {
        fallbackRedirect(); return;
    }
    if (!empty($allowedHosts) && !in_array($parsed['host'], $allowedHosts)) {
        fallbackRedirect(); return;
    }
    header('Location: ' . $targetUrl, true, 302);
    exit;
}

場景三:URL 規範化(去除片段、排序參數)

function normalizeUrl(string $url): string {
    $parsed = parse_url($url);
    $normalized = $parsed['scheme'] . '://' . $parsed['host'];
    if (!empty($parsed['port'])) $normalized .= ':' . $parsed['port'];
    $normalized .= $parsed['path'] ?? '/';
    if (!empty($parsed['query'])) {
        parse_str($parsed['query'], $params);
        ksort($params);  // 參數排序
        $normalized .= '?' . http_build_query($params);
    }
    // 故意丟棄 fragment
    return $normalized;
}

常見坑點總結

問題原因解決
雙重編碼已編碼字符串再次 urlencode編碼前檢查,或用 rawurldecode 先解碼
parse_url 解析失敗URL 缺少 Scheme 或含非法字符預處理補全 https://,或用 filter_var 驗證
get_headers 超時/失敗目標服務器無響應/證書錯誤設置 stream context timeout、verify_peer=false
中文參數亂碼編碼不一致(GBK vs UTF-8)統一項目為 UTF-8,輸入端強制轉換

總結

PHP 的 URL 處理函數族覆蓋了從底層編碼到高層語義解析的完整鏈路。核心記住:Query 參數用 urlencode,路徑用 rawurlencode;解析用 parse_url + parse_str;構建用 http_build_query;外部請求頭用 get_headers;SEO 元數據用 get_meta_tags。掌握這組組合拳,URL 相關需求輕鬆應對。

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