在開發 BBS 系統時,常會遇到使用者輸入資料的轉換與儲存問題。如何確保資料入庫安全、輸出時完整還原使用者原始內容,且不產生 XSS 風險,是每位 PHP 開發者必須面對的課題。本文整理一套經實測相對完善的處理函數庫,涵欏資料入庫前的過濾、不同情境下的輸出轉換,以及針對中文截斷的補充技巧。
以下程式碼適用於 Linux + PHP 4 + Oracle 8i 環境,但邏輯同樣適用於現代 PHP 版本(建議改用 mysqli 或 PDO 並配合預處理語句)。
<?php
//-- 標題、姓名等單行欄位入庫處理(去除首尾空格、轉義單引號、移除反斜線)
function trans_string_trim($str) {
$str = trim($str);
$str = eregi_replace("'", "''", $str); // 針對 Oracle 單引號轉義
$str = stripslashes($str);
return $str;
}
//-- 文章內容等多行欄位入庫處理(textarea 欄位,保留換行)
function trans_string($str) {
$str = eregi_replace("'", "''", $str);
$str = stripslashes($str);
return $str;
}
//-- 從資料庫讀出並顯示在表單中
//-- text 輸入框使用 trans 轉換,textarea 直接顯示無需轉換
//-- 顯示在網頁中,過濾 HTML 標籤(含連結),轉換換行與空格
function trans($string) {
$string = htmlspecialchars($string);
$string = ereg_replace(chr(10), "<br>", $string);
$string = ereg_replace(chr(32), " ", $string);
return $string;
}
//-- 顯示在網頁中,保留 HTML 標籤,僅轉換換行與空格
function trans_web($string) {
$string = ereg_replace(chr(10), "<br>", $string);
$string = ereg_replace(chr(32), " ", $string);
return $string;
}
//-- 顯示在網頁中,過濾 HTML 並去除首尾空格(適合顯示暱稱)
function trans_trim($string) {
$string = trim($string);
$string = htmlspecialchars($string);
$string = ereg_replace(chr(10), "<br>", $string);
$string = ereg_replace(chr(32), " ", $string);
return $string;
}
//-- 顯示在 span 標籤中,轉換換行、空格、雙引號
function trans_span($string) {
$string = ereg_replace(chr(10), "\n", $string);
$string = ereg_replace(chr(32), " ", $string);
$string = ereg_replace('"', """, $string);
return $string;
}
//-- 顯示 Cookie 內容,過濾 HTML 並還原單引號
function trans_cookie($str) {
$str = trans($str);
$str = stripslashes($str);
$str = eregi_replace("''", "'", $str);
return $str;
}
?>
當使用 substr 截取固定長度字串並置於 <span> 中顯示時,若截斷位置落在雙位元組中文字元中間,會導致 HTML 結構錯亂。解決方法是在 span 的屬性值結尾補一個空格,例如:
<span title="<?php echo trans_span(substr($content, 0, 50)) . ' '; ?>">...</span>
這樣可確保即使截到半個漢字,瀏覽器也能正確解析屬性值,不會破壞頁面結構。
htmlspecialchars($str, ENT_QUOTES, 'UTF-8') 防範 XSS。mb_substr 或 mb_strimwidth,支援多位元組編碼。eregi_replace、ereg_replace 等已移除的 POSIX 正則函數,改用 preg_replace。