Categories
Sói's Tutorials Uncategorized Web

[PHP] Note viết hàm chuyển mã (Encoding) tiếng Việt từ TCVN3 sang Unicode

Lỗi class UConvert[/caption] Vậy là đành phải tự viết một cái function chuyển đổi bảng mã thôi :’), cậy người không bằng cậy mình :v Nói vậy chứ mình cũng dạo thêm một vòng Google xem có ai làm chưa, thì thấy có một người có làm, nhưng làm chưa đến nơi. —-

Hàm chuyển mã Unicode sang VNI

Hàm chuyển mã tiếng Việt Unicode sang VNI, dùng thủ thuật tìm và thay thế từng âm tiết
function UNI_2_VNI ( $text2 )
{
 $text = utf8_encode($text2);
 $UNI = array ("À","à","Ã�","á","Â","â","Ã","ã","È","è","É","é","Ê","ê","ÃŒ","ì","Ã�","í","Ã’","ò","Ó","ó","Ô","ô","Õ","õ","Ù","ù","Ú","ú","Ã�","ý","Ä‚","ă","Ä�","Ä‘","Ĩ","Ä©","Ũ","Å©","Æ ","Æ¡","Ư","Æ°","Ạ","ạ","Ả","ả","Ấ","ấ","Ầ","ầ","Ẩ","ẩ","Ẫ","ẫ","Ậ","ậ","Ắ","ắ","Ằ","ằ","Ẳ","ẳ","Ẵ","ẵ","Ặ","ặ","Ẹ","ẹ","Ẻ","ẻ","Ẽ","ẽ","Ế","ế","Ề","á»�","Ể","ể","Ễ","á»…","Ệ","ệ","Ỉ","ỉ","Ị","ị","Ọ","á»�","Ỏ","á»�","á»�","ố","á»’","ồ","á»”","ổ","á»–","á»—","Ộ","á»™","Ớ","á»›","Ờ","á»�","Ở","ở","á» ","ỡ","Ợ","ợ","Ụ","ụ","Ủ","ủ","Ứ","ứ","Ừ","ừ","Ử","á»­","á»®","ữ","á»°","á»±","Ỳ","ỳ","á»´","ỵ","Ỷ","á»·","Ỹ","ỹ");
 $VNI = array ("AØ","aø","AÙ","aù","AÂ","aâ","AÕ","aõ","EØ","eø","EÙ","eù","EÂ","eâ","Ì","ì","Í","í","OØ","oø","OÙ","où","OÂ","oâ","OÕ","oõ","UØ","uø","UÙ","uù","YÙ","yù","AÊ","aê","Ñ","ñ","Ó","ó","UÕ","uõ","Ô","ô","Ö","ö","AÏ","aï","AÛ","aû","AÁ","aá","AÀ","aà","AÅ","aå","AÃ","aã","AÄ","aä","AÉ","aé","AÈ","aè","AÚ","aú","AÜ","aü","AË","aë","EÏ","eï","EÛ","eû","EÕ","eõ","EÁ","eá","EÀ","eà","EÅ","eå","EÃ","eã","EÄ","eä","Æ","æ","Ò","ò","OÏ","oï","OÛ","oû","OÁ","oá","OÀ","oà","OÅ","oå","OÃ","oã","OÄ","oä","ÔÙ","ôù","ÔØ","ôø","ÔÛ","ôû","ÔÕ","ôõ","ÔÏ","ôï","UÏ","uï","UÛ","uû","ÖÙ","öù","ÖØ","öø","ÖÛ","öû","ÖÕ","öõ","ÖÏ","öï","YØ","yø","Î","î","YÛ","yû","YÕ","yõ");
 for ($i = 0; $i < count($UNI); $i++)
 {
  $text = str_replace($UNI[$i], $VNI[$i], $text);
 }
 return $text;
}
Cách dùng
echo UNI_2_VNI("Xin chào các bạn, đây là chuỗi tiếng Việt Unicode đã được chuyển sang VNI");
Mở rộngBạn cũng có thể thay thế đoạn code này
$text = str_replace($UNI[$i], $VNI[$i], $text);
Thành thế này
$text = str_replace($VNI[$i], $UNI[$i], $text);
Để thực hiện việc chuyển từ mã VNI sang Unicode.Ngoài ra, bạn cũng có thể dùng Unikey, chuyển nội dung mảng $VNI thành những bảng mã khác.Ví dụ: Hàm chuyển từ bảng mã Unicode sang TCVN3
function UNI_2_TCVN3 ( $text )
{
 $UNI = array ( "à", "á", "ả", "ã", "ạ", "ă", "ằ", "ắ", "ẳ", "ẵ", "ặ", "â", "ầ", "ấ", "ẩ", "ẫ", "ậ", "đ", "è", "é", "ẻ", "ẽ", "ẹ", "ê", "ề", "ế", "ể", "ễ", "ệ", "ì", "í", "ỉ", "ĩ", "ị", "ò", "ó", "ỏ", "õ", "ọ", "ô", "ồ", "ố", "ổ", "ỗ", "ộ", "ơ", "ờ", "ớ", "ở", "ỡ", "ợ", "ù", "ú", "ủ", "ũ", "ụ", "ư", "ừ", "ứ", "ử", "ữ", "ự", "ỳ", "ý", "ỷ", "ỹ", "ỵ", "Ă", "Â", "Đ", "Ê", "Ô", "Ơ", "Ư");
 $TCVN3 = array ( "µ", "¸", "¶", "·", "¹","¨", "»", "¾", "¼", "½", "Æ","©", "Ç", "Ê", "È", "É", "Ë","®", "Ì", "Ð", "Î", "Ï", "Ñ","ª", "Ò", "Õ", "Ó", "Ô", "Ö","×","Ý", "Ø", "Ü", "Þ","ß", "ã", "á", "â", "ä","«", "å", "è", "æ", "ç", "é","¬", "ê", "í", "ë", "ì", "î", "ï", "ó", "ñ", "ò", "ô", "­", "õ", "ø", "ö", "÷", "ù","ú", "ý", "û", "ü", "þ", "¡", "¢", "§", "£", "¤", "¥", "¦");
 for ($i = 0; $i < count($UNI); $i++)
 {
  $text = str_replace($UNI[$i], $TCVN3[$i], $text);
 }
 return $text;
}
—-
https://kingno1.wordpress.com/2010/10/04/ham-chuy%E1%BB%83n-ma-unicode-sang-vni/
Tại sao mình nói là chưa đến nơi.
  • Thứ nhất vì bảng mã của Unicode và TCVN3 bạn này dùng mình thấy chưa chuẩn, mình dùng lại thì convert từ Unikey sang khác với của bạn này.
  • Thứ hai là thuật toán chưa hợp lý. Bạn này chỉ dùng hàm str_replace để thay thế ký tự đơn thuần từ TCVN3 sang UNICODE, tuy nhiên khi chạy vòng lặp lại là lặp hết mảng UNICODE hoặc TCVN3, đều này dẫn đến là nếu một chuỗi có một ký tự chuyển từ TCVN3 sang UNICODE ra 1 ký tự, ký tự này lại nằm trong mảng TCVN3 nữa thì nó sẽ lại bị thay thế một lần nữa.
Ví dụ trường hợp mình bị là đối với chuỗi
ch©u ®èc
Chuỗi này chuyển sang UNICODE đúng là châu đốc
châu đốc
Tuy nhiên khi dùng cách chuyển như bạn thì từ © trong từ ch©u sẽ bị chuyển thành â, từ â lại bị chuyển thành
Kết quả mình có:
[caption id="attachment_2127" align="alignnone" width="339"]Lỗi font Lỗi font[/caption]
Để khắc phục mình đưa ra ý tưởng là thay vì lập hết mảng TCVN3 hay Unicode thì mình duyệt qua từ ký tự của chuỗi. Sau đó xác định vị trí của ký tự trong mảng TCVN3, thay thế nó bằng ký tự ở mảng Unicode ở vị trí tương ứng. Như vậy mỗi ký tự trong chuỗi chỉ được duyệt qua và thay thế 1 lần thôi. Tránh tình trạng bị thay thế 2 lần như cách của bạn ở trên.
Cuối cùng ráp lại ta có chuỗi mới.
Thực hiện.

Đầu tiên tạo một mảng chứa các ký tự Unicode

$UNI = array("À","Á","Â","Ã","È","É","Ê","Ì","Í","Ò","Ó","Ô","Õ","Ù","Ú","Ý","à","á","â","ã","è","é","ê","ì","í","ò","ó","ô","õ","ù","ú","ý","Ă","ă","Đ","đ","Ĩ","ĩ","Ũ","ũ","Ơ","ơ","Ư","ư","Ạ","ạ","Ả","ả","Ấ","ấ","Ầ","ầ","Ẩ","ẩ","Ẫ","ẫ","Ậ","ậ","Ắ","ắ","Ằ","ằ","Ẳ","ẳ","Ẵ","ẵ","Ặ","ặ","Ẹ","ẹ","Ẻ","ẻ","Ẽ","ẽ","Ế","ế","Ề","ề","Ể","ể","Ễ","ễ","Ệ","ệ","Ỉ","ỉ","Ị","ị","Ọ","ọ","Ỏ","ỏ","Ố","ố","Ồ","ồ","Ổ","ổ","Ỗ","ỗ","Ộ","ộ","Ớ","ớ","Ờ","ờ","Ở","ở","Ỡ","ỡ","Ợ","ợ","Ụ","ụ","Ủ","ủ","Ứ","ứ","Ừ","ừ","Ử","ử","Ữ","ữ","Ự","ự","Ỳ","ỳ","Ỵ","ỵ","Ỷ","ỷ","Ỹ","ỹ"
);
Sau đó mình dùng Unikey convert cái này sang TCVN3 để có mảng các ký tự theo TCVN3 [caption id="attachment_2125" align="alignnone" width="460"]Unikey convert sang TCVN3 Unikey convert sang TCVN3[/caption]
$TCVN3 = array("µ","¸","¢","·","Ì","Ð","£","×","Ý","ß","ã","¤","â","ï","ó","ý","µ","¸","©","·","Ì","Ð","ª","×","Ý","ß","ã","«","â","ï","ó","ý","¡","¨","§","®","Ü","Ü","ò","ò","¥","¬","¦","­","¹","¹","¶","¶","Ê","Ê","Ç","Ç","È","È","É","É","Ë","Ë","¾","¾","»","»","¼","¼","½","½","Æ","Æ","Ñ","Ñ","Î","Î","Ï","Ï","Õ","Õ","Ò","Ò","Ó","Ó","Ô","Ô","Ö","Ö","Ø","Ø","Þ","Þ","ä","ä","á","á","è","è","å","å","æ","æ","ç","ç","é","é","í","í","ê","ê","ë","ë","ì","ì","î","î","ô","ô","ñ","ñ","ø","ø","õ","õ","ö","ö","÷","÷","ù","ù","ú","ú","þ","þ","û","û","ü","ü"
);
Bây giờ đến giai đoạn tách chuỗi, ban đầu mình dùng hàm str_split, nhưng hàm này tách riêng từng byte (từng char, ngay cả dấu sắc, dấu hỏi,..) Do mình dùng tiếng Việt là mã Multi byte, do vậy mình đã sửa chuyển sang dùng hàm mb_split
$arr1=mb_split($text,’UTF-8′);
Và để đếm ký tự multi byte thì cũng có hàm riêng cho nó
$len = mb_strlen($text, ‘UTF-8’);
Cái vòng lập duyệt qua từng char
for($i=0;$i<$len; $i++){
		$char=mb_substr($text, $i, 1, 'UTF-8');
		$result[] = $char;
		//echo mb_substr($text, $i, 1, 'UTF-8');
		//echo '<br>';
		$key=array_search($char,$TCVN3);
		echo $char.' co ma: '.$key;
		echo '<br>';
		if($key!=''){
			$arr2[$i]=$UNI[$key];
		}else{
			$arr2[$i]=$char;
		}
	}
Cuối cùng, ráp mảng kết quả lại bằng hàm implode
$text=implode(“”,$arr2);

Code full hàm chuyển đổi bảng mã tiếng Việt TCVN3 sang Unicode của mình

function TCVN3_2_UNI($text){
	$UNI = array("À","Á","Â","Ã","È","É","Ê","Ì","Í","Ò","Ó","Ô","Õ","Ù","Ú","Ý","à","á","â","ã","è","é","ê","ì","í","ò","ó","ô","õ","ù","ú","ý","Ă","ă","Đ","đ","Ĩ","ĩ","Ũ","ũ","Ơ","ơ","Ư","ư","Ạ","ạ","Ả","ả","Ấ","ấ","Ầ","ầ","Ẩ","ẩ","Ẫ","ẫ","Ậ","ậ","Ắ","ắ","Ằ","ằ","Ẳ","ẳ","Ẵ","ẵ","Ặ","ặ","Ẹ","ẹ","Ẻ","ẻ","Ẽ","ẽ","Ế","ế","Ề","ề","Ể","ể","Ễ","ễ","Ệ","ệ","Ỉ","ỉ","Ị","ị","Ọ","ọ","Ỏ","ỏ","Ố","ố","Ồ","ồ","Ổ","ổ","Ỗ","ỗ","Ộ","ộ","Ớ","ớ","Ờ","ờ","Ở","ở","Ỡ","ỡ","Ợ","ợ","Ụ","ụ","Ủ","ủ","Ứ","ứ","Ừ","ừ","Ử","ử","Ữ","ữ","Ự","ự","Ỳ","ỳ","Ỵ","ỵ","Ỷ","ỷ","Ỹ","ỹ"
);
	$TCVN3 = array("µ","¸","¢","·","Ì","Ð","£","×","Ý","ß","ã","¤","â","ï","ó","ý","µ","¸","©","·","Ì","Ð","ª","×","Ý","ß","ã","«","â","ï","ó","ý","¡","¨","§","®","Ü","Ü","ò","ò","¥","¬","¦","­","¹","¹","¶","¶","Ê","Ê","Ç","Ç","È","È","É","É","Ë","Ë","¾","¾","»","»","¼","¼","½","½","Æ","Æ","Ñ","Ñ","Î","Î","Ï","Ï","Õ","Õ","Ò","Ò","Ó","Ó","Ô","Ô","Ö","Ö","Ø","Ø","Þ","Þ","ä","ä","á","á","è","è","å","å","æ","æ","ç","ç","é","é","í","í","ê","ê","ë","ë","ì","ì","î","î","ô","ô","ñ","ñ","ø","ø","õ","õ","ö","ö","÷","÷","ù","ù","ú","ú","þ","þ","û","û","ü","ü"
);
	$arr1=mb_split($text,'UTF-8');
	$arr2=array();
	$len = mb_strlen($text, 'UTF-8');
	for($i=0;$i<$len; $i++){
		$char=mb_substr($text, $i, 1, 'UTF-8');
		$result[] = $char;
		//echo mb_substr($text, $i, 1, 'UTF-8');
		//echo '<br>';
		$key=array_search($char,$TCVN3);
		echo $char.' co ma: '.$key;
		echo '<br>';
		if($key!=''){
			$arr2[$i]=$UNI[$key];
		}else{
			$arr2[$i]=$char;
		}
	}
	$text=implode("",$arr2);
	//echo $text;
	//echo $result[1];
	/* for($i=0;$i<count($arr1);$i++){
		$key=array_search($arr1[$i],$TCVN3);
		echo $arr1[$i].' co ma: '.$key;
		echo '<br>';
		$arr2[$i]=$UNI[$key];
	} */
	//$text=implode("",$arr2);
	/* for ($i=0;$i<count($UNI);$i++){
		$text = str_replace($TCVN3[$i], $UNI[$i], $text);
	} */
	return $text;
}
Kết quả [caption id="attachment_2126" align="alignnone" width="336"]Hàm php chuyển mã tiếng Việt Hàm php chuyển mã tiếng Việt[/caption] Hi vọng giúp được mọi người, đối với các bảng mã khác cũng tương tụ vậy nhé -soiqualang_chentreu-

Tham khảo

https://stackoverflow.com/questions/38126940/php-str-split-and-utf8-polish-characters https://stackoverflow.com/questions/29710635/fatal-error-call-to-undefined-function-mb-split http://php.net/manual/en/function.mb-split.php https://www.w3schools.com/php/func_string_implode.asp http://php.net/manual/en/function.str-split.php https://stackoverflow.com/questions/2959222/get-the-index-value-of-an-array-in-php    ]]>

Leave a Reply

Your email address will not be published. Required fields are marked *