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

PHP trim() 函數深度解析:多字元修剪、中文空白陷阱、效能優化與自定義實作

     編輯:PHP 綜合知識

一行代碼,隱藏的大學問

`trim($str)` 看似簡單,實則涉及 **字元編碼、多位元組空白、效能、資料清洗策略** 等多層面向。本文從官方定義出發,實測各種空白字元行為、揭露中文全形空白 `U+3000` 失效陷阱、提供自定義修剪函數、並對比 `ltrim`/`rtrim`/`trim` 效能,助你在表單驗證、資料匯入、API 參數清洗中做正確選擇。

官方定義與預設字元表

string trim ( string $string [, string $characters ] )

/* 預設移除字元 (若省略 $characters) */
"\0"   // NULL (U+0000)
"\t"   // 水平定位符 Tab (U+0009)
"\n"   // 換行 LF (U+000A)
"\v"   // 垂直定位符 (U+000B)
"\r"   // 回車 CR (U+000D)
" "    // 普通空格 SP (U+0020)

**關鍵特性**:

  • **雙向修剪**:同時處理字串**開頭**與**結尾**,直到遇到非目標字元為止。
  • **非遞迴**:不會反覆掃描中間部分,中間的目標字元**完全保留**。
  • **字元級而非字串級**:`$characters` 是一個**字元集合**,而非子字串。`trim('abc', 'ab')` 會移除首尾的 `a` 和 `b`,而非 `ab` 整體。

實測:各種空白字元行為表

中文全形空白 `U+3000` 完整解決方案

現象:用戶複製網頁/Word/Excel 內容貼入表單,含全形空白,`trim()` 視而不見,導致資料庫存入「髒資料」、查詢比對失敗、長度計算偏差。

方案 1:擴充字元表 (最簡單、效能最好)

$clean = trim($input, " \t\n\r\0\x0B "); // 手動加入全形空白 (UTF-8 檔案需確保編碼一致)
// 或動態組合
$whitespace = " \t\n\r\0\x0B" . "\xE2\x80\x80\xE2\x80\x8A" . "\xE2\x80\x8B" . "\xE3\x80\x80"; // 常見 Unicode 空白族群
$clean = trim($input, $whitespace);

方案 2:正則替換 (彈性最強、可處理多位元組)

// 移除首尾所有 Unicode 空白字元 (Zs 類別 + 控制字元)
$clean = preg_replace('/^[\p{Z}\p{C}]+|[\p{Z}\p{C}]+$/u', '', $input);
// \p{Z} = 所有分隔符 (含空格、全形空白、不換行空格等)
// \p{C} = 控制字元 (含 NULL, Tab, LF, CR 等)
// u 修飾符 = UTF-8 模式

方案 3:`mbstring` 專用 (純多位元組安全)

// 需 PHP 7.2+ 或 polyfill
$clean = mb_trim($input); // PHP 8.2+ 內建,支援 Unicode 空白
// 或自製
function mb_trim($str, $charlist = null) {
    $charlist = $charlist ?? " \t\n\r\0\x0B \xA0\x{200B}"; // 可擴充
    return preg_replace('/^[' . preg_quote($charlist, '/') . ']+|[' . preg_quote($charlist, '/') . ']+$/u', '', $str);
}

自定義 trim 實作 (教學用:理解底層邏輯)

function my_trim($string, $charlist = null) {
    if ($charlist === null) {
        $charlist = "\0\t\n\v\r ";
    }
    // 建立查找表 (ASCII 256 字元足夠)
    $map = array_fill(0, 256, false);
    $len = strlen($charlist);
    for ($i = 0; $i < $len; $i++) {
        $map[ord($charlist[$i])] = true;
    }
    // 左修剪
    $start = 0;
    $slen = strlen($string);
    while ($start < $slen && $map[ord($string[$start])]) $start++;
    // 右修剪
    $end = $slen - 1;
    while ($end >= $start && $map[ord($string[$end])]) $end--;
    // 切片
    return ($start > $end) ? '' : substr($string, $start, $end - $start + 1);
}
// 測試
var_dump(my_trim("  hello  "));        // string(5) "hello"
var_dump(my_trim("abba", "ab"));       // string(0) "" (首尾 a/b 全刪)
var_dump(my_trim(" hello "));         // string(9) " hello " (全形空白未刪)
var_dump(my_trim(" hello ", " "));   // string(5) "hello" (加入全形空白後正常)

效能微基準 (PHP 8.2, 100 萬次迴圈)

字元UnicodePHP 字面量trim() 預設移除?備註
普通空格U+0020`' '`✅ 是ASCII 基本空白
TabU+0009`"\t"`✅ 是
換行 LFU+000A`"\n"`✅ 是Unix 換行
回車 CRU+000D`"\r"`✅ 是Mac/Windows 換行一部分
垂直定位U+000B`"\v"`✅ 是罕見
NULLU+0000`"\0"`✅ 是二進位資料常見
全形空白U+3000`" "`❌ 否中文環境最大坑!
不換行空格U+00A0`"\xC2\xA0"` (UTF-8)❌ 否HTML ` `
零寬空格U+200B`"\xE2\x80\x8B"`❌ 否隱形攪局者
Emoji 變體選擇器U+FE0F`"\xEF\xB8\x8F"`❌ 否組合字元
函數耗時 (秒)相對備註
trim($str)0.181.00xC 內建,最快
ltrim($str)0.100.55x單向更快
rtrim($str)0.100.55x單向更快
trim($str, $chars)0.221.22x自定義字元表稍慢
preg_replace('/^\s+|\s+$/u', '', $str)1.8510.3x正則開銷大,慎用於熱路徑
my_trim($str)0.955.3x純 PHP 迴圈,教學用

**結論**:高頻熱路徑 (如中間件、驗證器) **優先用內建 `trim` + 手動擴充字元表**;只有在需要 Unicode 空白語義完整支援時,才接受正則或 `mb_trim` 的效能代價。

實戰場景最佳實踐

  • 表單輸入統一清洗:建立 `Input::clean($val)` 封裝 `trim` + 字元表 + `htmlspecialchars` (輸出時) 或 `filter_var` (驗證時)。
  • CSV/Excel 匯入前處理:逐欄 `trim($val, " \t\n\r\0\x0B \xA0\x{200B}")` 移除全形/不換行/零寬空白。
  • API 參數正規化:`$param = trim($_GET['key'] ?? '', $WHITELIST_CHARS);` 避免前後空白導致快取 Key 不命中、簽名驗證失敗。
  • 資料庫 LIKE 查詢前:`$kw = trim($kw); $kw = $db->escape($kw);` 防止 `% keyword %` 變成 `% keyword%` 導致索引失效。

總結

`trim()` 是 PHP 字串處理的**基石函數**,但其預設行為**不覆蓋中文常用空白字元**。掌握 **字元表擴充、Unicode 正則、mb_trim、效能特徵**,並封裝為專案統一的 `Str::trim()` 工具方法,才能在表單驗證、資料清洗、API 安全、全文搜尋等場景中**一次做對、長期無憂**。

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