2008-09-26 28 views
19

Nó thường xảy ra rằng các nhân vật như é được chuyển thành à ©, mặc dù collation cho MySQL DB, bàn và lĩnh vực được thiết lập để utf8_general_ci. Mã hóa trong Loại nội dung cho trang cũng được đặt thành UTF8.Thực hành tốt nhất trong PHP và MySQL với chuỗi quốc tế

Tôi biết về utf8_encode/decode, nhưng tôi không hoàn toàn chắc chắn về vị trí và cách sử dụng nó.

Tôi đã đọc bài viết "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)", nhưng tôi cần một số con trỏ cụ thể về MySQL/PHP.

Câu hỏi: Làm cách nào để đảm bảo rằng người dùng đã nhập dữ liệu chứa ký tự quốc tế không bị hỏng?

Trả lời

13

Trên cái nhìn đầu tiên tại http://www.nicknettleton.com/zine/php/php-utf-8-cheatsheet Tôi nghĩ rằng một điều quan trọng là mất tích (có lẽ tôi bỏ qua cái này). Tùy thuộc vào cài đặt và/hoặc cấu hình MySQL của bạn, bạn phải đặt mã hóa kết nối để MySQL biết mã hóa bạn đang mong đợi ở phía máy khách (nghĩa là phía máy khách của kết nối MySQL, bạn nên sử dụng tập lệnh PHP). Bạn có thể thực hiện việc này bằng cách phát hành theo cách thủ công các yêu cầu

SET NAMES utf8 

truy vấn trước bất kỳ truy vấn nào khác bạn gửi tới máy chủ MySQL.

Nếu your're sử dụng PDO ở phía bên PHP bạn có thể thiết lập kết nối tự động phát hành truy vấn này trên tất cả (lại) kết nối bằng cách sử dụng

$db=new PDO($dsn, $user, $pass); 
$db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8"); 

khi khởi tạo kết nối db của bạn.

+0

Nó mentoined trong các ý kiến ​​ở đâu đó, nhưng có, rất khó để bỏ lỡ! – Jrgns

+2

Đối với bất kỳ ai chỉ đọc sách này (tính đến tháng 3 năm 2010), bài viết được tham chiếu bây giờ có thể được tìm thấy tại http://developer.loftdigital.com/blog/php-utf-8-cheatsheet – bdl

0

Để có độ chính xác unicode tốt hơn, bạn nên sử dụng utf8_unicode_ci (mặc dù tài liệu hơi mơ hồ về sự khác biệt). Bạn cũng nên chắc chắn rằng những lá cờ Mysql sau được thiết lập một cách chính xác -

  • mặc định ký tự-set = utf8
  • bỏ qua ký tự-set-client-handshake // quan trọng vì vậy khách hàng không thực thi mã hóa khác

Có thể đặt trong tệp cấu hình mysql (trong tab [mysqld]) hoặc tại thời gian chạy bằng cách gửi truy vấn thích hợp.

2

Những điều bạn nên làm:

  • Hãy chắc chắn rằng Apache đặt ra UTF-8 nội dung. Thực hiện điều này trong httpd.conf của bạn hoặc sử dụng hàm header() của PHP để thực hiện thủ công.
  • Đảm bảo kết nối cơ sở dữ liệu của bạn là UTF8. SET NAMES utf8 thực hiện thủ thuật.
  • Đảm bảo tất cả các bảng của bạn được đặt thành UTF8.
  • Đảm bảo tất cả các tệp PHP và mẫu của bạn được mã hóa dưới dạng UTF8 nếu bạn lưu trữ các ký tự quốc tế trong chúng.

Bạn thường không phải làm gì nhiều khi sử dụng các số mb_string hoặc utf8_encode/decode -functions khi bạn thực hiện việc này.

8

Ghép và bộ ký tự không giống nhau. Collation của bạn cần phải phù hợp với bộ ký tự, vì vậy nếu bộ ký tự của bạn là utf-8, vì vậy nên collation. Chọn collation sai sẽ không garble dữ liệu của bạn mặc dù - Chỉ cần làm cho chuỗi so sánh/phân loại công việc sai.

Điều đó nói rằng, có một số địa điểm, nơi bạn có thể đặt cài đặt bộ ký tự trong PHP. Tôi khuyên bạn nên sử dụng utf-8 trong suốt, nếu có thể. Các địa điểm cần bộ ký tự được chỉ định là:

  • Cơ sở dữ liệu. Điều này có thể được thiết lập trên cơ sở dữ liệu, bảng và cấp trường, và thậm chí trên một cấp cho mỗi truy vấn.
  • Kết nối giữa PHP và cơ sở dữ liệu.
  • Đầu ra HTTP; Đảm bảo rằng tiêu đề HTTP Content-Type chỉ định utf-8. Bạn có thể đặt các giá trị mặc định trong PHP và trong Apache, hoặc bạn có thể sử dụng hàm header của PHP.
  • Đầu vào HTTP. Nói chung, các biểu mẫu sẽ được gửi trong cùng một bộ ký tự khi trang được phân phối, nhưng để đảm bảo, bạn nên chỉ định thuộc tính accept-charset. Ngoài ra, hãy đảm bảo rằng URL được mã hóa utf-8 hoặc tránh sử dụng các ký tự không phải ascii trong các tham số của GET (và GET).

utf8_encode/chức năng giải mã được đặt tên lạ. Chúng đặc biệt chuyển đổi giữa latin1 (ISO-8859-1) và utf-8. Nếu mọi thứ trong ứng dụng của bạn là utf-8, bạn sẽ không phải sử dụng chúng nhiều.

Có ít nhất hai gotchas liên quan đến utf-8 và PHP. Đầu tiên là các hàm dựng sẵn của PHP mong đợi các chuỗi là một byte. Đối với rất nhiều hoạt động, điều này không quan trọng, nhưng nó có nghĩa là bạn không thể dựa vào strlen và các chức năng khác. Có một sự giảm xuống tốt về các giới hạn tại this page. Thông thường, nó không phải là một vấn đề lớn, nhưng đặc biệt là khi sử dụng thư viện của bên thứ ba, bạn cần phải nhận thức được rằng mọi thứ có thể bùng nổ về điều này. Một tùy chọn cũng là sử dụng phần mở rộng mb_string, trong đó có tùy chọn để thay thế tất cả các hàm phiền hà bằng các lựa chọn thay thế nhận thức utf-8. Nó vẫn không phải là một giải pháp chống đạn 100%, nhưng nó sẽ làm việc cho hầu hết các trường hợp.

Một vấn đề khác là một số cài đặt của PHP vẫn bật cài đặt magic_quotes. Vấn đề này là trực giao với utf-8, nhưng có thể dẫn đến một số đầu gãi. Tắt nó đi, vì lợi ích của chính bạn.

0

Bất kể ngôn ngữ nó được viết bằng, nếu bạn đã tạo ra một ứng dụng cho phép một loạt các mã hóa, xử lý ra từ miếng:

  • Xác định mã hóa
    • bằng cách nào đó bạn muốn tìm hiểu xem bạn đang xử lý loại mã hóa nào, nếu không, sẽ khá vô nghĩa khi xem xét nó hơn nữa. Bạn sẽ kết thúc với các ký tự rác.
  • Xử lý byte của bạn
    • suy nghĩ của những chuỗi ít như 'chuỗi' của nhân vật, và nhiều hơn nữa như danh sách của byte
    • PHP đặc biệt lén lút. Đừng để nó cắt ngắn dữ liệu của bạn một cách nhanh chóng.Nếu bạn đang regexing một chuỗi UTF-8, chắc chắn rằng bạn xác định nó như vậy
  • Store cho màn hình LCD
    • Một lần nữa, bạn không muốn cắt ngắn dữ liệu. Nếu bạn đang lưu trữ một câu bằng tiếng Anh, bạn cũng có thể lưu trữ một tập hợp các chữ cái tiếng Quan Thoại không? Làm thế nào về tiếng Ả Rập? Điều nào sẽ đòi hỏi nhiều không gian nhất? Tài khoản cho nó.
Các vấn đề liên quan