爬蟲資料、匯入 CSV/XML、API 回傳常夾帶不可見的 ASCII 控制字元 (0-31, 127),導致 XML 解析失敗、資料庫寫入錯誤、前端顯示異常。
/**
* 移除 ASCII 控制字元,保留換行、Tab 等常用空白字元
* @param string $str 輸入字串
* @return string 清理後字串
*/
function filter_ascii_control($str) {
if (!$str) return '';
$clean = '';
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$ord = ord($str[$i]);
// 保留:Tab(9), LF(10), CR(13), 可列印字元(32-126)
if ($ord === 9 || $ord === 10 || $ord === 13 || ($ord >= 32 && $ord <= 126)) {
$clean .= $str[$i];
} else {
$clean .= ' '; // 其它控制字元替換為空格
}
}
return trim($clean);
}
function filter_ascii_control_regex($str) {
// 移除除 \t\n\r 以外的控制字元
return preg_replace('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/u', ' ', $str);
}
function sanitize_input($data) {
// 1. 移除控制字元
$data = filter_ascii_control($data);
// 2. 統一編碼為 UTF-8
$data = mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data, 'UTF-8, BIG5, GBK, ASCII', true));
// 3. 移除 BOM
$data = preg_replace('/^\\xEF\\xBB\\xBF/', '', $data);
// 4. 修剪首尾空白
$data = trim($data);
// 5. 多重空白合併
$data = preg_replace('/\\s+/', ' ', $data);
return $data;
}
$dirty = "Hello\x00World\x1F\x7F\r\nTab:\tEnd";
echo bin2hex($dirty) . "\n"; // 原始 hex
$clean = filter_ascii_control($dirty);
echo bin2hex($clean) . "\n"; // 清理後 hex
echo $clean; // 可讀輸出
Invalid character 錯誤Incorrect string value