問題重現
<?php
$str = '測試•特殊符號•五一快樂!'; // UTF-8
echo iconv('UTF-8', 'GBK', $str);
// Notice: iconv(): Detected an illegal character
// 輸出: 測試 (後續內容全部丟失)
?>
解決方案://IGNORE 後綴
<?php
$str = '測試•特殊符號•五一快樂!';
echo iconv('UTF-8', 'GBK//IGNORE', $str);
// 輸出: 測試特殊符號五一快樂! (• 等非法字符被靜默移除)
?>
原理說明
//IGNORE:遇到目標編碼無法表示的字符,**跳過該字符,繼續處理後續內容**,不報錯、不中斷。
//TRANSLIT:嘗試找視覺相近字符替換(如 • → *),失敗則報錯並中斷。**不推薦**。
對比驗證
<?php
$tests = [
'純中文測試',
'中文•符號',
'Emoji😊測試',
'生僻字𪛖測試', // U+2A6D6 擴展區
];
foreach ($tests as $t) {
echo "原文: $t\n";
echo "IGNORE: " . iconv('UTF-8', 'GBK//IGNORE', $t) . "\n";
echo "TRANSLIT: " . @iconv('UTF-8', 'GBK//TRANSLIT', $t) . "\n";
echo "---\n";
}
?>
最佳實踐封裝
<?php
function safeIconv($str, $toEncoding, $fromEncoding = 'UTF-8') {
// 統一使用 IGNORE 策略,保證不中斷
return @iconv($fromEncoding, $toEncoding . '//IGNORE', $str);
}
// 使用
$gbk = safeIconv($utf8Str, 'GBK');
$big5 = safeIconv($utf8Str, 'BIG5');
?>
現代替代:mb_convert_encoding
<?php
// 內部自動忽略非法字符,無需後綴
$gbk = mb_convert_encoding($str, 'GBK', 'UTF-8');
// 性能較 iconv 低,但行為更穩定
?>
避坑指南
- **關鍵業務數據 (訂單號、身份證、金額) 禁用 //IGNORE**,應預先驗證字符集合法性。
- 日誌、展示類非關鍵數據可放心使用 //IGNORE。
- 全站統一 UTF-8 可徹底避免轉碼痛點。
- 檢查代碼庫是否存在裸露
iconv('UTF-8', 'GBK', ...),批量添加 //IGNORE。