iconv 簡介
iconv() 是 PHP 內置的字符集轉換函數(依賴 libiconv 庫),支持 100+ 字符集互轉,是處理多編碼數據(如抓取 GB2312 頁面存入 UTF-8 數據庫)的核心工具。
安裝與啟用
Linux
# 通常隨 PHP 內置編譯(--with-iconv)
# 若無,安裝 libiconv 庫後重新編譯 PHP
yum install libiconv-devel
./configure --with-iconv=/usr/local/libiconv ...
Windows
- PHP 5.3+ 內置
php_iconv.dll,php.ini 取消註釋 extension=php_iconv.dll。
- 關鍵:需將 GNU libiconv 的
iconv.dll、charset.dll 放入系統 PATH(如 C:\Windows\System32 或 PHP 目錄),否則啟用失敗。
基本語法與常用編碼
string iconv ( string $in_charset , string $out_charset , string $str )
| 常用編碼標識 | 說明 |
| UTF-8 | 通用 Unicode 編碼 |
| GB2312 / GBK / CP936 | 簡體中文(GBK 擴展 GB2312) |
| BIG5 / BIG5-HKSCS | 繁體中文 |
| ISO-8859-1 | 西歐語言(Latin-1) |
| Shift_JIS / EUC-JP | 日語 |
| EUC-KR | 韓語 |
核心參數技巧://IGNORE 與 //TRANSLIT
<?php
$str = "你好—世界"; // 包含長破音號 U+2014
// 1. 直接轉換:遇到目標編碼無法表示的字符會報錯並截斷後續內容
echo iconv('UTF-8', 'GB2312', $str); // 可能輸出 "你好" 後截斷
// 2. //IGNORE:忽略無法轉換的字符,保留其餘
echo iconv('UTF-8', 'GB2312//IGNORE', $str); // 輸出 "你好世界"(長破音號被丟棄)
// 3. //TRANSLIT:嘗試音譯/近似映射(視 libiconv 版本支持度)
echo iconv('UTF-8', 'GB2312//TRANSLIT', $str); // 可能輸出 "你好--世界" 或類似
// 4. 組合使用:先嘗試音譯,失敗再忽略
echo iconv('UTF-8', 'GB2312//TRANSLIT//IGNORE', $str);
?>
實戰場景:抓取網頁編碼轉換
<?php
function fetchAndConvert($url, $targetCharset = 'UTF-8') {
$html = file_get_contents($url);
if (!$html) return false;
// 1. 嘗試從 HTTP Header 獲取編碼
$charset = 'UTF-8';
foreach ($http_response_header as $header) {
if (stripos($header, 'Content-Type:') === 0) {
if (preg_match('/charset=([\w-]+)/i', $header, $m)) {
$charset = strtoupper($m[1]);
}
}
}
// 2. 從 HTML meta 獲取(備選)
if ($charset === 'UTF-8' && preg_match('/<meta[^>]+charset=["\']?([\w-]+)/i', $html, $m)) {
$charset = strtoupper($m[1]);
}
// 3. 統一轉為目標編碼
if (strtoupper($charset) !== $targetCharset) {
$html = iconv($charset, $targetCharset . '//IGNORE', $html);
}
return $html;
}
?>
iconv 系列函數速查
| 函數 | 用途 |
iconv_strlen($str, $charset) | 按字符數計算長度(非字節) |
iconv_substr($str, $offset, $length, $charset) | 按字符截取子串 |
iconv_strpos($haystack, $needle, $offset, $charset) | 按字符查找位置 |
iconv_mime_encode() | MIME 頭編碼(郵件主題等) |
iconv_mime_decode() | MIME 頭解碼 |
iconv_get_encoding() | 獲取當前 iconv 內部編碼設置 |
iconv_set_encoding() | 設置 input/internal/output 編碼 |
常見錯誤與解決
| 錯誤現象 | 原因 | 解決 |
iconv(): Wrong charset | 編碼名稱拼寫錯誤或不支持 | 用 iconv -l 查看系統支持列表;統一用標準名(UTF-8 而非 utf8) |
| 轉換後字符串變短/丟失 | 目標編碼無法表示源字符,且未用 //IGNORE | 添加 //IGNORE 或 //TRANSLIT//IGNORE |
| Windows 下啟用失敗 | 缺少 libiconv DLL | 下載 GNU libiconv 二進制包,放入 PATH 目錄 |
| 性能瓶頸 | 大量小字符串反覆調用 | 批量處理、或改用 mb_convert_encoding()(需 mbstring 擴展) |
iconv vs mb_convert_encoding
iconv:C 库级、依賴 libiconv、支持編碼最全、速度極快、內存效率高。
mb_convert_encoding:PHP mbstring 擴展、純 PHP 實現、支持 mbstring 相關功能(正則、分詞)、API 更面向對象。
- 建議:簡單轉換用
iconv;需配合多字節正則/分詞用 mbstring。