2009-06-24 35 views

Trả lời

6
function is_utf8($string) { 
return preg_match('%^(?: 
[\x09\x0A\x0D\x20-\x7E] # ASCII 
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 
)*$%xs', $string); 

}

Tôi đã kiểm tra. Chức năng này có hiệu quả.

0

nếu gửi nó đến u từ máy chủ

echo $_SERVER['HTTP_ACCEPT_CHARSET']; 
+1

Bạn có thể có UTF-8 ** và ** ISO chuỗi mã hóa trong vòng 1 request/tập tin. Tiêu đề HTTP sẽ trợ giúp như thế nào trong mọi trường hợp? – DanFromGermany

33

Đừng phát minh lại bánh xe. Có một hàm dựng sẵn cho tác vụ đó: mb_check_encoding().

mb_check_encoding($string, 'UTF-8'); 
+1

Đây là loại giải pháp của tôi! –

+0

Điều gì sẽ xảy ra nếu bạn chưa cài đặt tiện ích đó? – CMCDragonkai

+2

@CMCDragonkai Nếu dữ liệu của bạn ở định dạng nhiều byte (như UTF-8), bạn chắc chắn nên cài đặt phần mở rộng PHP cung cấp các chức năng hoạt động chính xác trên đầu vào của bạn. Nếu bạn sử dụng 'strlen' trên một chuỗi UTF-8, ví dụ, bạn sẽ nhận được độ dài sai nếu đầu vào chứa các ký tự không phải ASCII. – soulmerge

6

Tốt hơn, hãy sử dụng cả hai giải pháp trên.

function isUtf8($string) { 
    if (function_exists("mb_check_encoding") && is_callable("mb_check_encoding")) { 
     return mb_check_encoding($string, 'UTF8'); 
    } 

    return preg_match('%^(?: 
      [\x09\x0A\x0D\x20-\x7E]   # ASCII 
     | [\xC2-\xDF][\x80-\xBF]    # non-overlong 2-byte 
     | \xE0[\xA0-\xBF][\x80-\xBF]  # excluding overlongs 
     | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 
     | \xED[\x80-\x9F][\x80-\xBF]  # excluding surrogates 
     | \xF0[\x90-\xBF][\x80-\xBF]{2}  # planes 1-3 
     | [\xF1-\xF3][\x80-\xBF]{3}   # planes 4-15 
     | \xF4[\x80-\x8F][\x80-\xBF]{2}  # plane 16 
    )*$%xs', $string); 

} 
+1

Gọi tới cả hàm function_exists() và is_callable() là dư thừa, bạn có thể bỏ qua một trong số chúng. Nhưng vì is_callable() được thiết kế để kiểm tra xem tham số có phải là một cuộc gọi lại hợp lệ hay không (xem liên kết bên dưới), tôi sẽ sử dụng function_exists() để làm cho nó dễ đọc hơn. Liên kết đến kiểu gọi lại giả: http://php.net/manual/en/language.pseudo-types.php#language.types.callback – soulmerge

+0

@ nikc.org - Tôi không hiểu - tại sao bạn muốn thử nghiệm liệu hàm 'mb_check_encoding' có tồn tại không? – JDelage

+2

@JDelage vì đó là một phần của phần mở rộng (php.net/manual/en/book.mbstring.php) không được đảm bảo để luôn có mặt. –

15

Chỉ cần một mặt lưu ý:

Bạn không thể xác định xem một chuỗi cho trước được mã hóa theo UTF-8. Bạn chỉ có thể xác định xem một chuỗi đã cho là dứt khoát là không phải là được mã hóa bằng UTF-8 hay không. Hãy xem một câu hỏi liên quan here:

Bạn không thể phát hiện nếu một chuỗi cho trước (hoặc chuỗi byte) là một UTF-8 mã hóa văn bản như ví dụ mỗi loạt các UTF-8 octet còn a là hợp lệ (nếu vô nghĩa) loạt các bảng chữ cái Latinh-1 (hoặc một số mã hóa khác). Tuy nhiên không phải mọi chuỗi hợp lệ Latin-1 octet đều hợp lệ với chuỗi UTF-8.

0

Không có câu trả lời nào ở trên là chính xác. Có, họ có thể đang làm việc. Nếu bạn nhận được câu trả lời với hàm preg_replace, bạn có đang cố gắng giết máy chủ của mình nếu bạn xử lý nhiều sự khuấy động không? Sử dụng hàm PHP thuần túy này không có regex, làm việc 100% thời gian và nó nhanh hơn.

if(function_exists('grk_Is_UTF8') === FALSE){ 
    function grk_Is_UTF8($String=''){ 
     # On va calculer la longeur de la chaîne 
     $Len = strlen($String); 

     # On va boucler sur chaque caractère 
     for($i = 0; $i < $Len; $i++){ 
      # On va aller chercher la valeur ASCII du caractère 
      $Ord = ord($String[$i]); 
      if($Ord > 128){ 
       if($Ord > 247){ 
        return FALSE; 
       } elseif($Ord > 239){ 
        $Bytes = 4; 
       } elseif($Ord > 223){ 
        $Bytes = 3; 
       } elseif($Ord > 191){ 
        $Bytes = 2; 
       } else { 
        return FALSE; 
       } 

       # 
       if(($i + $Bytes) > $Len){ 
        return FALSE; 
       } 

       # On va boucler sur chaque bytes/caractères 
       while($Bytes > 1){ 
        # +1 
        $i++; 

        # On va aller chercher la valeur ASCII du caractère/byte 
        $Ord = ord($String[$i]); 
        if($Ord < 128 OR $Ord > 191){ 
         return FALSE; 
        } 

        # Parfait 
        $Bytes--; 
       } 
      } 
     } 

     # Vrai 
     return TRUE; 
    } 
} 
1

mb_detect_encoding($string); sẽ trả về bộ ký tự thực tế $string. mb_check_encoding($string, 'UTF-8'); sẽ trở lại TRUE nếu bộ ký tự của $string là UTF-8 khác FALSE

Các vấn đề liên quan