2012-06-13 31 views
7

Tôi đang làm việc cho các khách hàng quốc tế có tất cả các bảng chữ cái rất khác nhau và vì vậy tôi đang cố gắng có được một tổng quan về quy trình làm việc hoàn chỉnh giữa PHP và MySQL để đảm bảo mã hóa ký tự được chèn chính xác. Tôi đã đọc một loạt các hướng dẫn về điều này nhưng vẫn còn có câu hỏi (có nhiều điều để tìm hiểu) và nghĩ rằng tôi có thể chỉ cần đặt tất cả lại với nhau ở đây và yêu cầu.Quy trình làm việc UTF8 PHP, MySQL tóm tắt

PHP

header('Content-Type:text/html; charset=UTF-8'); 
mb_internal_encoding('UTF-8'); 

HTML

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 
<form accept-charset="UTF-8"> .. </form> 

(mặc dù sau này là không bắt buộc và là một đề xuất nhưng tôi tin tưởng Tôi thà đề nghị như không làm gì cả)

MySQL

CREATE database_name DEFAULT CHARACTER SET utf8; hoặc ALTER database_name DEFAULT CHARACTER SET utf8; và/hoặc sử dụng utf8_general_ci làm collation kết nối MySQL.

(nó là important to note đây rằng điều này sẽ làm tăng kích thước cơ sở dữ liệu nếu nó sử dụng varchar)

kết nối

mysql_query("SET NAMES 'utf8'"); 
mysql_query("SET CHARACTER_SET utf8"); 

doanh nghiệp Logic

phát hiện nếu không UTF8 với mb_detect_encoding() và chuyển đổi với ivon().
xác nhận chuỗi quá dài UTF8 và UTF16

$body=preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]|(?<=^|[\x00-\x7F])[\x80-\xBF]+|([\xC0\xC1]|[\xF0-\xFF])[\x80-\xBF]*|[\xC2-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})/','�',$body); 
$body=preg_replace('/\xE0[\x80-\x9F][\x80-\xBF]|\xED[\xA0-\xBF][\x80-\xBF]/S','?', $body); 

Câu hỏi

  • mb_internal_encoding('UTF-8') cần thiết trong PHP 5.3 và cao hơn và nếu như vậy không có nghĩa là tôi phải sử dụng tất cả các chức năng đa byte thay vì các chức năng chính của nó như mb_substr() thay vì substr()?

  • vẫn cần kiểm tra các lỗi đầu vào không đúng định dạng và nếu có thì chức năng/lớp đáng tin cậy sẽ làm như thế nào? Tôi có thể không muốn loại bỏ dữ liệu xấu và không biết đủ về chuyển ngữ.

  • nó có thực sự là utf8_general_ci hoặc đúng hơn là utf8_bin?

  • có điều gì đó thiếu trong quy trình trên không?

nguồn:

http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ 
http://webcollab.sourceforge.net/unicode.html 
http://stackoverflow.com/a/3742879/1043231 
http://www.adayinthelifeof.nl/2010/12/04/about-using-utf-8-fields-in-mysql/ 
http://akrabat.com/php/utf8-php-and-mysql/ 
+1

ok, vậy câu hỏi là gì? –

+0

xin lỗi tôi đã đấu tranh với việc đăng câu hỏi này vì có vẻ như lỗi stackoverflow một số url nguồn của tôi là mã và ném lỗi .... hoạt động bây giờ ... – Dominik

+0

mb_internal_encoding ('UTF-8') là cần thiết nếu kết quả mb_internal_encoding() không phải là UTF-8. –

Trả lời

1

nên nó thực sự là utf8_general_ci hay đúng hơn utf8_bin?

Bạn phải sử dụng utf8_bin cho Case-nhạy cảm tìm kiếm, nếu không utf8_general_ci

được mb_internal_encoding ('UTF-8') cần thiết trong PHP 5.3 và cao hơn và nếu như vậy không có nghĩa là tôi phải sử dụng tất cả các hàm đa byte thay vì các hàm lõi của nó như mb_substr() thay vì substr()?

Có tất nhiên, nếu bạn có chuỗi nhiều byte, bạn cần hàm gia đình mb_ * để làm việc, ngoại trừ chức năng chuẩn php an toàn nhị phân như str_replace(); (và vài người khác)

vẫn cần kiểm tra các lỗi đầu vào không đúng định dạng và nếu vậy thì chức năng/lớp đáng tin cậy là gì? Tôi có thể không muốn loại bỏ dữ liệu xấu và không biết đủ về chuyển ngữ.

Hmm, bạn không thể kiểm tra.

+3

Điểm thứ 2 và thứ 3 là không thực tế. Điểm thứ hai phụ thuộc vào những gì "lọc" là về ... bạn vẫn có thể làm '(int) $ _ GET ['utf8var']', ví dụ.Các hàm chuỗi của PHP là thân thiện với nhị phân. Trừ khi bạn đang rối tung mọi thứ, 'str_replace()' và gia đình vẫn làm việc (với ngoại lệ duy nhất của bí danh UTF8). – Christian

6
  • mb_internal_encoding('UTF-8') không tự làm bất cứ điều gì, chỉ đặt tham số mã hóa mặc định cho mỗi chức năng mb_. Nếu bạn không sử dụng bất kỳ chức năng mb_ nào, nó sẽ không tạo ra bất kỳ sự khác biệt nào. Nếu bạn đang có, nó có ý nghĩa để thiết lập nó, do đó bạn không cần phải vượt qua các thông số $encoding mỗi lần riêng biệt.
  • IMO mb_detect_encoding chủ yếu là vô ích vì về cơ bản không thể phát hiện chính xác mã hóa văn bản không xác định. Bạn nên biết mã hóa một blob của văn bản là gì bởi vì bạn có một đặc điểm kỹ thuật về nó, hoặc bạn cần phải phân tích cú pháp dữ liệu meta thích hợp như tiêu đề hoặc thẻ meta nơi mã hóa được chỉ định.
  • Sử dụng mb_check_encoding để kiểm tra xem một văn bản màu có hợp lệ trong mã hóa mà bạn mong đợi ở đó thường đủ hay không. Nếu không, loại bỏ nó và ném một lỗi thích hợp.
  • Về:

    không có nghĩa là tôi phải sử dụng tất cả các chức năng đa byte thay vì các chức năng cốt lõi của nó

    Nếu bạn đang thao tác với chuỗi chứa các ký tự nhiều byte, sau đó có, bạn cần phải sử dụng các chức năng mb_ để tránh nhận kết quả sai. Các hàm chuỗi lõi chỉ hoạt động trên một mức byte, không phải là một mức ký tự, đó là những gì bạn thường muốn khi làm việc với các chuỗi.

  • utf8_general_ci so với utf8_bin chỉ tạo sự khác biệt khi đối chiếu, tức là sắp xếp và so sánh các chuỗi. Với dữ liệu utf8_bin được xử lý dưới dạng nhị phân, tức là chỉ dữ liệu giống hệt hệt nhau. Với utf8_general_ci một số logic được áp dụng, ví dụ: Các loại "é" cùng với "e" và chữ hoa được coi là bằng với chữ thường.