在php中可以用mb_detect_encoding()()函數來判斷一個字串是否為某種編碼,具體使用方法和注意事項如下:
需要注意的是,要使用mb_detect_encoding函數,必須開啟php中的mbstring擴充(開啟php.ini配置,重啟服務即可)。
判斷方式如下所示:
if( mb_detect_encoding($str, 'UTF-8', true) )
{
//是UTF-8格式的字元
}
網上有些人說這個函數判斷不太準備,其實大致還是沒問題的。
例子,利用mb_detect_encoding()判斷字元是否為uft-8編碼。
$encode = mb_detect_encoding($q, array('GB2312','GBK','UTF-8'));
echo $encode."<br/>";
if($encode=="GB2312")
{
$q = iconv("GBK","UTF-8",$q);
}
else if($encode=="GBK")
{
$q = iconv("GBK","UTF-8",$q);
}
else if($encode=="EUC-CN")
{
$q = iconv("GBK","UTF-8",$q);
}
else//CP936
{
//$q = iconv("GB2312","UTF-8",$q);
}
可是 mb_detect_encoding 存在一個硬傷,經常出現判斷不準確的情況。或許這樣就可以解決:
// 使用 iconv 轉換並判斷是否等值,效率不高
function is_utf8 ($str) {
if ($str === iconv('UTF-8', 'UTF-8//IGNORE', $str)) {
return 'UTF-8';
}
}
// 多種編碼的情況
function detect_encoding ($str) {
foreach (array('GBK', 'UTF-8') as $v) {
if ($str === iconv($v, $v . '//IGNORE', $str)) {
return $v;
}
}
}
通過以上方式得到字串編碼資訊後,就可以利用 iconv 或 mb_convert_encoding 來轉換編碼了
例子
<?php
/**
* 檢測檔案編碼
* @param string $file 檔案路徑
* @return string|null 返回 編碼名 或 null
*/
function detect_encoding($file) {
$list = array('GBK', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'ISO-8859-1');
$str = file_get_contents($file);
foreach ($list as $item) {
$tmp = mb_convert_encoding($str, $item, $item);
if (md5($tmp) == md5($str)) {
return $item;
}
}
return null;
}
/**
* 自動解析編碼讀入檔案
* @param string $file 檔案路徑
* @param string $charset 讀取編碼
* @return string 返回讀取內容
*/
function auto_read($file, $charset='UTF-8') {
$list = array('GBK', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'ISO-8859-1');
$str = file_get_contents($file);
foreach ($list as $item) {
$tmp = mb_convert_encoding($str, $item, $item);
if (md5($tmp) == md5($str)) {
return mb_convert_encoding($str, $charset, $item);
}
}
return "";
}
例子
我建立三個檔案:text1.txt text2.txt text3.txt
分別以ASCII UTF-8 UNICODE 的編碼方式儲存
代碼如下:
<?php
define ('UTF32_BIG_ENDIAN_BOM' , chr(0x00) . chr(0x00) . chr(0xFE) . chr(0xFF));
define ('UTF32_LITTLE_ENDIAN_BOM', chr(0xFF) . chr(0xFE) . chr(0x00) . chr(0x00));
define ('UTF16_BIG_ENDIAN_BOM' , chr(0xFE) . chr(0xFF));
define ('UTF16_LITTLE_ENDIAN_BOM', chr(0xFF) . chr(0xFE));
define ('UTF8_BOM' , chr(0xEF) . chr(0xBB) . chr(0xBF));
function detect_utf_encoding($text) {
$first2 = substr($text, 0, 2);
$first3 = substr($text, 0, 3);
$first4 = substr($text, 0, 3);
if ($first3 == UTF8_BOM) return 'UTF-8';
elseif ($first4 == UTF32_BIG_ENDIAN_BOM) return 'UTF-32BE';
elseif ($first4 == UTF32_LITTLE_ENDIAN_BOM) return 'UTF-32LE';
elseif ($first2 == UTF16_BIG_ENDIAN_BOM) return 'UTF-16BE';
elseif ($first2 == UTF16_LITTLE_ENDIAN_BOM) return 'UTF-16LE';
}
function getFileEncoding($str){
$encoding=mb_detect_encoding($str);
if(empty($encoding)){
$encoding=detect_utf_encoding($str);
}
return $encoding;
}
$file = 'text1.txt';
echo getFileEncoding(file_get_contents($file)); // 輸出ASCII
echo '<br />';
$file = 'text2.txt';
echo getFileEncoding(file_get_contents($file)); // 輸出UTF-8
echo '<br />';
$file = 'text3.txt';
echo getFileEncoding(file_get_contents($file)); // 輸出UTF-16LE
echo '<br />';
?>
注意:要把php.ini中 extension=php_mbstring.dll 前的;號去掉,重啟apache就可以了。