字符串處理是 Web 開發中最高頻的任務之一:防 XSS 的 HTML 標籤過濾、換行符與 <br> 互轉、多餘空白字符合併、首尾敏感字符修剪、腳本標籤清理等。本文提供一個可直接投入項目的 cls_string_filter 靜態工具類,涵蓋 10 個高頻場景,代碼經過規範化、註釋完善並修復原版潛在缺陷(如正則轉義錯誤、變量拼寫不一致)。
<?php
/**
* 字符串過濾與替換工具類
* 所有方法均為靜態,無狀態,線程安全
*/
class cls_string_filter
{
/**
* 將換行符轉為 HTML 換行標籤
* @param string $string
* @return string
*/
public static function nl2br(string $string): string
{
return nl2br($string);
}
/**
* 將 HTML 換行標籤轉為換行符
* 支援 <br>、<br/>、<br /> 等寫法
* @param string $string
* @return string
*/
public static function br2nl(string $string): string
{
$patterns = ['/<br\s*\/?\s*>/i'];
return preg_replace($patterns, "\n", $string);
}
/**
* 合併連續空白字符為單個空格
* 包含空格、製表符、換行符等
* @param string $string
* @return string
*/
public static function merge_spaces(string $string): string
{
// 將任意連續空白字符替換為單個空格
return preg_replace('/\s+/', ' ', $string);
}
/**
* 合併連續 <br> 標籤為單個
* @param string $string
* @return string
*/
public static function merge_brs(string $string): string
{
// 匹配連續的 <br>、<br/>、<br />(不區分大小寫)
return preg_replace('/(<br\s*\/?\s*>)+/i', '<br>', $string);
}
/**
* 移除所有 HTML 標籤(保留文本內容)
* @param string $string
* @param string $allowable_tags 可選,允許保留的標籤,如 '<b><i>'
* @return string
*/
public static function strip_tags(string $string, string $allowable_tags = ''): string
{
return strip_tags($string, $allowable_tags);
}
/**
* 字符串轉小寫(支援多字節/UTF-8)
* @param string $string
* @return string
*/
public static function strtolower(string $string): string
{
return mb_strtolower($string, 'UTF-8');
}
/**
* 字符串轉大寫(支援多字節/UTF-8)
* @param string $string
* @return string
*/
public static function strtoupper(string $string): string
{
return mb_strtoupper($string, 'UTF-8');
}
/**
* 修剪字符串首尾指定字符集合
* @param string $string
* @param string $char_list 字符集合,默認修剪空白字符;支持範圍如 'a-zA-Z0-9'
* @return string
*/
public static function trim(string $string, string $char_list = "\\s"): string
{
// 對特殊正則字符進行轉義
$char_list = preg_quote($char_list, '/');
// 構建首尾匹配模式
$pattern = '/^[' . $char_list . ']+|[' . $char_list . ']+$/u';
return preg_replace($pattern, '', $string);
}
/**
* 移除 <style> 標籤及其內容
* @param string $string
* @return string
*/
public static function strip_style(string $string): string
{
// 匹配 <style ...> ... </style>,跨行、不貪婪
$pattern = '/<style[^>]*>.*?<\/style>/is';
return preg_replace($pattern, '', $string);
}
/**
* 移除高危 HTML 標籤及屬性(防 XSS 基礎防護)
* 針對 script、iframe、style、html、body、title、meta、?、% 等
* @param string $string
* @return string
*/
public static function strip_html_tags(string $string): string
{
// 移除完整標籤對及其內容
$patterns = [
'/<\/?(script|iframe|style|html|body|title|meta)[^>]*>/is',
'/<\?.*?\?>/s', // PHP 標籤
'/%[^%]*%/s', // 模板引擎標記(視項目調整)
];
$string = preg_replace($patterns, '', $string);
// 移除危險屬性:on*、javascript:、vbscript:、data:、expression()
$string = preg_replace('/\s(on\w+|href|src|action)\s*=\s*["\'][^"\']*?(javascript|vbscript|data|expression)\s*:/i', '', $string);
return $string;
}
}
<?php
$html = "<div> Hello\n\nWorld! <br/><br/><script>alert(1)</script></div>";
echo cls_string_filter::strip_html_tags($html);
// 輸出: " Hello World! <br><br>"
echo cls_string_filter::merge_spaces($html);
// 輸出: " Hello World!
"
echo cls_string_filter::br2nl("Line1<br/>Line2<br />Line3");
// 輸出: "Line1\nLine2\nLine3"
echo cls_string_filter::trim(" \t\n Hello World \n\t ", " \t\n");
// 輸出: "Hello World"
echo cls_string_filter::strip_style("<style>body{color:red}</style>Content");
// 輸出: "Content"
?>
| 原版問題 | 修正方案 |
|---|---|
merge_spaces 正則 /\s(?=\s)/ 邏輯錯誤,無法合併多個空格 | 改為 /\s+/ 直接替換為單空格 |
merge_brs 正則轉義混亂 /((<br\/>?>)+)/i | 改為 /(<br\s*\/?\s*>)+/i 正確匹配各種寫法 |
trim 方法變量 $fine、$chars 拼寫錯誤導致報錯 | 重寫邏輯,使用 preg_quote 安全轉義,支持 Unicode /u 模式 |
strip_html_tags 正則過於簡陋,無法處理屬性型 XSS | 新增危險屬性過濾,覆蓋 on* 事件、偽協議等 |
| 缺少類型聲明、返回類型、命名空間、現代 PHP 寫法 | 補全 PHP 7.4+ 嚴格類型、string 類型提示、mb_* 多字節安全 |
strip_html_tags 僅提供基礎過濾,**不能替代成熟的 HTML 淨化庫**。生產環境富文本輸出請使用:
v-html (Vue) / dangerouslySetInnerHTML (React) 時,**務必**經過後端凈化truncate($string, $length, $suffix='...') 截斷(按字符而非字節)slugify($string) 生成 URL 友好 slug(中文拼音/去特殊字符)mask($string, $visibleStart=3, $visibleEnd=3, $maskChar='*') 手機/身份證掩碼highlight($string, $keywords, $tag='mark') 關鍵詞高亮