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

PHP 實用工具函數集 (第三輯):URL 獲取、全半形轉換、HTML 處理、路徑轉換、連結提取與表格解析

     編輯:PHP 綜合知識

前言

實務開發中常需處理 URL、HTML、路徑、表格等結構化資料。本文整理 6 個高復用工具函數:當前 URL 獲取、全形數字轉半形、HTML 標籤清理/轉換、相對路徑轉絕對、連結提取、HTML 表格轉陣列,附原理分析與改良版。

一、獲取當前腳本完整 URL

function get_php_url(): string {
    if (!empty($_SERVER['REQUEST_URI'])) {
        return $_SERVER['REQUEST_URI'];
    }
    // 相容舊環境/CLI
    $script = $_SERVER['PHP_SELF'] ?? '';
    $query = $_SERVER['QUERY_STRING'] ?? '';
    return $query ? $script . '?' . $query : $script;
}

// 改良版:取得完整絕對 URL
function getCurrentFullUrl(): string {
    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || ($_SERVER['SERVER_PORT'] ?? 80) == 443 
        ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'] ?? ($_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT']);
    $uri = get_php_url();
    return "{$scheme}://{$host}{$uri}";
}

二、全形數字/符號轉半形

function GetAlabNum(string $fnum): string {
    // 全形 → 半形映射 (含數字、常用符號)
    $full = ['0','1','2','3','4','5','6','7','8','9','.','-','+',':'];
    $half = ['0','1','2','3','4','5','6','7','8','9','.','-','+',':'];
    
    $fnum = str_replace($full, $half, $fnum);
    
    // 進一步過濾:僅保留 ASCII 可列印字元 (移除中文等)
    $result = '';
    $len = strlen($fnum);
    for ($i = 0; $i < $len; $i++) {
        if (ord($fnum[$i]) > 0x80) { $i++; continue; } // 跳過雙位元組字元
        $result .= $fnum[$i];
    }
    
    return $result !== '' ? $result : '0';
}

// 現代版:支援 Unicode 正規化 (需 intl 擴展)
function toHalfWidthModern(string $str): string {
    if (class_exists('Normalizer')) {
        $str = Normalizer::normalize($str, Normalizer::NFKC); // 全形字母/數字/符號自動轉半形
    }
    // 保留 ASCII 可列印字元
    return preg_replace('/[^\x20-\x7E]/', '', $str);
}

三、HTML 標籤處理

Text2Html:純文字轉 HTML 安全輸出

function Text2Html(string $txt): string {
    $txt = str_replace('  ', ' ', $txt);          // 雙空格 → 單空格 (視需求)
    $txt = str_replace('<', '<', $txt);        // < → <
    $txt = str_replace('>', '>', $txt);        // > → >
    $txt = preg_replace('/[\r\n]{1,}/', "
\r\n", $txt); // 換行 →
return $txt; } // 現代標準:htmlspecialchars (必加 ENT_QUOTES | ENT_HTML5) function Text2HtmlModern(string $txt): string { return nl2br(htmlspecialchars($txt, ENT_QUOTES | ENT_HTML5, 'UTF-8')); }

ClearHtml:移除 HTML 標籤 (保留純文字)

function ClearHtml(string $str): string {
    $str = str_replace('<', '<', $str);
    $str = str_replace('>', '>', $str);
    return $str;
}

// 正確做法:strip_tags (可選保留標籤)
function ClearHtmlModern(string $str, string $allowable_tags = ''): string {
    return strip_tags($str, $allowable_tags);
    // 範例:strip_tags($html, '


') 保留段落、換行、粗體 }

四、相對路徑轉絕對路徑 (HTML 內容)

function relative_to_absolute(string $content, string $baseUrl): string {
    // 解析基礎 URL
    $parsed = parse_url($baseUrl);
    $scheme = $parsed['scheme'] ?? 'http';
    $host = $parsed['host'] ?? '';
    if (!$host) return $content;
    
    $base = "{$scheme}://{$host}";
    
    // href="/path" → href="https://host/path"
    $content = preg_replace('/href\s*=\s*["\']\//', 'href="' . $base . '/', $content);
    // src="/path" → src="https://host/path"
    $content = preg_replace('/src\s*=\s*["\']\//', 'src="' . $base . '/', $content);
    
    return $content;
}

// 更完整版:處理所有相對路徑 (../, ./, 無前綴)
function makeLinksAbsolute(string $html, string $baseUrl): string {
    $dom = new DOMDocument();
    @$dom->loadHTML('' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    $xpath = new DOMXPath($dom);
    
    foreach (['href', 'src'] as $attr) {
        foreach ($xpath->query("//*[@{$attr}]") as $node) {
            $value = $node->getAttribute($attr);
            if ($value && !preg_match('/^[a-z]+:/i', $value) && $value[0] !== '#') {
                $node->setAttribute($attr, rtrim($baseUrl, '/') . '/' . ltrim($value, '/'));
            }
        }
    }
    return $dom->saveHTML();
}

五、提取所有連結

function get_all_url(string $html): array {
    // 正則版 (簡單、快速、但不嚴謹)
    preg_match_all('/"\'\s]+)["\']?[^>]*>([^<]+)<\/a>/i', $html, $matches);
    return ['name' => $matches[2], 'url' => $matches[1]];
}

// DOM 版 (標準、健壯、支援巢狀/屬性順序不固定)
function getAllLinksDom(string $html): array {
    $dom = new DOMDocument();
    @$dom->loadHTML('' . $html);
    $links = [];
    foreach ($dom->getElementsByTagName('a') as $a) {
        $href = $a->getAttribute('href');
        $text = trim($a->textContent);
        if ($href) $links[] = ['url' => $href, 'name' => $text];
    }
    return $links;
}

六、HTML 表格解析為陣列

逐行解析 (簡易版)

function get_tr_array(string $tableHtml): array {
    // 將 ... 轉為 CSV 風格分隔
    $table = preg_replace("']*>'si", '"', $tableHtml);
    $table = str_replace('', '",', $table);
    $table = str_replace('', "{tr}", $table);
    
    // 移除所有 HTML 標籤
    $table = preg_replace("'<[/!]*?[^<>]*?>'si", "", $table);
    // 移除空白字元  
    $table = str_replace(['\r','\n','\t',' ',' '], '', $table);
    
    $rows = explode('{tr}', $table);
    array_pop($rows); // 最後空元素
    return $rows; // 每行如 '"cell1","cell2","cell3"'
}

完整儲存格解析 (二維陣列)

function get_td_array(string $tableHtml): array {
    // 移除 table, tr 標籤,保留 td 內容結構
    $table = preg_replace("']*>'si", "", $tableHtml);
    $table = preg_replace("']*>'si", "", $table);
    $table = preg_replace("']*>'si", "", $table);
    $table = str_replace('', "{tr}", $table);
    $table = str_replace('', "{td}", $table);
    
    // 清理標籤與空白
    $table = preg_replace("'<[/!]*?[^<>]*?>'si", "", $table);
    $table = preg_replace("'([\r\n])[\s]+'", "", $table);
    $table = str_replace([' ', ' '], '', $table);
    
    $rows = explode('{tr}', $table);
    array_pop($rows);
    
    $result = [];
    foreach ($rows as $row) {
        $cells = explode('{td}', $row);
        array_pop($cells);
        $result[] = $cells;
    }
    return $result;
}

// 現代 DOM 版 (推薦生產環境)
function parseTableDom(string $html): array {
    $dom = new DOMDocument();
    @$dom->loadHTML('' . $html);
    $tables = [];
    foreach ($dom->getElementsByTagName('table') as $table) {
        $rows = [];
        foreach ($table->getElementsByTagName('tr') as $tr) {
            $cells = [];
            foreach ($tr->getElementsByTagName('td') as $td) {
                $cells[] = trim($td->textContent);
            }
            if ($cells) $rows[] = $cells;
        }
        if ($rows) $tables[] = $rows;
    }
    return $tables; // 多表格支援
}

七、提取英文單詞 (去重、排序)

function split_en_str(string $str, bool $distinct = true): array {
    preg_match_all('/([a-zA-Z]+)/', $str, $matches);
    $words = $matches[1];
    if ($distinct) $words = array_unique($words);
    sort($words, SORT_STRING | SORT_FLAG_CASE); // 不區分大小寫排序
    return $words;
}

// 範例
$text = "Hello world, hello PHP! World is beautiful.";
print_r(split_en_str($text));
/*
Array
(
    [0] => beautiful
    [1] => hello
    [2] => is
    [3] => php
    [4] => world
)
*/

總結與現代化建議

功能舊版做法現代推薦關鍵優勢
URL 獲取$_SERVER 手動拼接封裝函數 + parse_url可測試、可復用、支援代理標頭
全半形轉換陣列映射 + 位元組檢查Normalizer::NFKC (intl)Unicode 標準、支援字母/符號、無遺漏
HTML 清理str_replace 手動htmlspecialchars / strip_tags標準、安全、支援編碼
路徑轉絕對正則替換 href/srcDOMDocument + DOMXPath結構化、不漏標籤、支援巢狀
連結提取preg_match_allDOMDocument getElementsByTagName健壯、標準、編碼安全
表格解析正則字串替換DOMDocument 遍歷 tr/td正確處理 rowspan/colspan、巢狀表格

核心原則:**HTML 解析請用 DOMDocument,不要用正則**。正則無法正確處理巢狀標籤、屬性順序、編碼實體、條件註解等真實世界複雜性。PHP 的 `DOMDocument` 雖然 API 稍顯繁瑣,但配合 `DOMXPath` 是處理 HTML/XML 的正統之道。

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