Cách hiển thị ký tự UTF-8 trong PHP

Nhận các ký tự kỳ lạ như Â thay vì hoặc ’? . Nó có thể xảy ra khi MySQL và PHP được nâng cấp hoặc khi dữ liệu được lưu trữ không chính xác hoặc ứng dụng đang gửi bộ ký tự không chính xác [hoặc bị thiếu] tới trình duyệt. PHP chưa hỗ trợ UTF-8 nguyên bản trong nhiều chức năng xử lý chuỗi của nó [phiên bản 6 sẽ có khi được phát hành]

Đoạn ngắn của nó…

1. Không sử dụng






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


4. Sử dụng





p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


5. Hãy cẩn thận khi sử dụng strlen[], nó có thể đếm số byte và không tính ký tự

2. Gửi tiêu đề utf-8 từ php trước khi bạn gửi bất kỳ nội dung nào của trang.






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


6

3. Ngay khi bạn kết nối với mysql, hãy thực hiện






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


7 để đặt mã hóa của kết nối thành utf-8, điều này thường cần thiết trong các ứng dụng php/mysql

4. You want this meta tag in the section to be absolutely safe:






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


8

5. Chúc may mắn

Thời gian dài của nó…Tại sao nó lại xảy ra?

Đầu tiên, thật hữu ích khi biết một chút về UTF-8. Bỏ qua điều này nếu bạn đã quen

UTF-8 sử dụng một hoặc nhiều byte 8 bit để lưu trữ một ký tự, không giống như ASCII và những người bạn chỉ sử dụng một byte cho mỗi ký tự. Nó tiết kiệm không gian hơn so với những người anh em họ của nó [UTF-16, UTF-32] khi phần lớn các ký tự có thể được mã hóa dưới dạng một byte, như trường hợp của hầu hết văn bản tiếng Anh, nhưng với lợi ích bổ sung mà bạn vẫn có thể . Nó sử dụng các bit quan trọng nhất của mỗi byte làm bit tiếp theo [để biểu thị rằng [các] byte sau tạo thành một phần của cùng một ký tự]. Chính vì lý do này mà UTF-8 hiển thị không đúng cách dẫn đến các ký tự lạ

UTF-8 tương thích ngược với ASCII — tất cả các ký tự lên đến 127 đều giống nhau trong cả hai mã hóa. Điều này ít nhất làm cho văn bản tiếng Anh dễ đọc nếu UTF-8 được hiểu không chính xác là bộ ký tự ASCII hoặc ISO 8859. Tuy nhiên, chính những cách hiểu sai này đã khiến các ký tự kỳ lạ xuất hiện

Thật không may, PHP chưa hỗ trợ UTF-8 nguyên bản trong nhiều chức năng xử lý chuỗi của nó [phiên bản 6 sẽ hỗ trợ khi được phát hành], nhưng điều đó không có nghĩa là bạn không thể làm việc với nó — bạn chỉ cần cẩn thận một chút. Hãy lấy strlen[] làm ví dụ. với văn bản ASCII đơn giản, strlen[] trả về số lượng ký tự trong một chuỗi. Nó thực hiện điều này bằng cách đếm số byte được sử dụng để chứa dữ liệu. Nó không biết về [và không thể phát hiện] UTF-8 và sẽ đếm số byte một cách mù quáng chứ không phải số ký tự thực tế. Do đó, sự hiện diện của bất kỳ ký tự multibyte nào trong chuỗi của bạn sẽ khiến bạn có độ dài không chính xác

Một vấn đề chắc chắn bạn sẽ gặp phải là khi người dùng lợi dụng một ứng dụng khác để tạo một số văn bản được dán vào biểu mẫu HTML của bạn và gửi đi. Ví dụ: Microsoft Word sử dụng Unicode trong nội bộ và tự động chuyển đổi các ký tự như dấu ngoặc kép và dấu gạch ngang thành “dấu ngoặc kép thông minh” và dấu gạch ngang tự động. Đây là những ký tự chính xác, nhưng các ký hiệu nằm bên ngoài bộ ký tự ASCII nên khi được sao chép và dán, văn bản được gửi dưới dạng UTF-8 và bạn kết thúc bằng các ký tự nhiều byte ở khắp mọi nơi. Nếu bạn lưu trữ văn bản này và sau đó gửi lại cho trình duyệt mà không thông báo rằng bạn đang gửi UTF-8, các ký tự bổ sung sẽ xuất hiện

Paul Tero là một nhà phát triển web tự do, sống và làm việc tại Brighton, Anh. Ông có hơn 20 năm kinh nghiệm trong nhiều dự án và nền tảng khác nhau. Tìm hiểu thêm về Paul ↬

Bản tin email

Email [đập vỡ] của bạn

Mẹo hàng tuần về giao diện người dùng & UX.
Được hơn 200.000 người tin cậy.

  • Xem trực tiếp vào tháng 12. thứ 8

  • Các mẫu thiết kế giao diện Đào tạo UX

  • Các mẫu thiết kế giao diện thông minh, khóa học 8h-video

  • Bắt đầu miễn phí

  • Giao diện người dùng SmashingConf 2023

Bài viết này chủ yếu dựa vào các con số và nhằm mục đích cung cấp sự hiểu biết về các bộ ký tự, Unicode, UTF-8 và các vấn đề khác nhau có thể phát sinh

Đây là một câu chuyện bắt nguồn từ những ngày đầu tiên của máy tính. Câu chuyện có một cốt truyện, tốt, loại. Nó có sự cạnh tranh và âm mưu, cũng như đi qua vô số quốc gia và ngôn ngữ. Có xung đột và giải pháp, và một kết thúc có hậu. Nhưng trọng tâm chính là các nhân vật. 110.116 người trong số họ. Đến cuối câu chuyện, tất cả họ sẽ tìm thấy vị trí độc nhất của riêng mình trên thế giới này

Bài viết này sẽ theo dõi kỹ hơn một số ký tự đó, khi chúng di chuyển từ máy chủ Web đến trình duyệt và ngược lại. Đồng thời, bạn sẽ tìm hiểu thêm về lịch sử của các ký tự, bộ ký tự, Unicode và UTF-8, cũng như lý do tại sao các dấu hỏi và ký tự có dấu lẻ đôi khi hiển thị trong cơ sở dữ liệu và tệp văn bản

Cảnh báo. Bài viết này chứa rất nhiều con số, bao gồm một chút nhị phân — tốt nhất nên tiếp cận sau tách cà phê buổi sáng của bạn

ASCII

Máy tính chỉ xử lý số chứ không phải chữ cái, vì vậy điều quan trọng là tất cả các máy tính đều đồng ý về số nào đại diện cho chữ cái nào

Giả sử máy tính của tôi sử dụng số 1 cho A, 2 cho B, 3 cho C, v.v. và máy tính của bạn sử dụng số 0 cho A, 1 cho B, v.v. Nếu tôi gửi cho bạn tin nhắn HELLO, thì các số 8, 5, 12, 12, 15 sẽ lướt qua dây. Nhưng đối với bạn 8 có nghĩa là tôi, vì vậy bạn sẽ nhận và giải mã nó dưới dạng IFMMP. Để giao tiếp hiệu quả, chúng ta cần thống nhất về cách mã hóa tiêu chuẩn các ký tự

Để đạt được mục tiêu này, vào những năm 1960, Hiệp hội Tiêu chuẩn Hoa Kỳ đã tạo ra một mã hóa 7 bit có tên là Mã tiêu chuẩn Hoa Kỳ để trao đổi thông tin [ASCII]. Trong mã hóa HELLO này là 72, 69, 76, 76, 79 và sẽ được truyền kỹ thuật số dưới dạng 1001000 1000101 1001100 1001100 1001111. Sử dụng 7 bit cho 128 giá trị có thể từ 0000000 đến 1111111, vì vậy ASCII có đủ chỗ cho tất cả các chữ cái Latinh viết thường và viết hoa, cùng với từng chữ số, dấu chấm câu phổ biến, dấu cách, tab và các ký tự điều khiển khác. Năm 1968, Tổng thống Hoa Kỳ Lyndon Johnson đã công bố chính thức - tất cả các máy tính phải sử dụng và hiểu ASCII

Tự mình thử

Có rất nhiều bảng ASCII có sẵn, hiển thị hoặc mô tả 128 ký tự. Hoặc bạn có thể tạo một cái của riêng mình với một chút CSS, HTML và Javascript, hầu hết là để làm cho nó hiển thị đẹp mắt



p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}

for [var i=0; i

9. Nó nhận một số và biến nó thành một ký tự. Thực ra 4 dòng HTML và Javascript dưới đây đều cho ra cùng một kết quả. Tất cả đều khiến trình duyệt hiển thị các số ký tự 72, 69, 76, 76 và 79

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];

Cũng lưu ý cách Firefox hiển thị các ký tự không in được [như xóa lùi và thoát] trong cột đầu tiên. Một số trình duyệt hiển thị khoảng trống hoặc dấu chấm hỏi. Firefox ép bốn chữ số thập lục phân vào một hộp nhỏ

Thêm sau khi nhảy. Tiếp tục đọc bên dưới ↓

Nâng cao kỹ năng UX của bạn với Khóa học video về mẫu thiết kế giao diện thông minh, thư viện video 8h của Vitaly Friedman. Với hàng trăm ví dụ thực tế, hướng dẫn thiết kế và danh sách kiểm tra UX. Kiểm tra bản xem trước miễn phí [video miễn phí, 15 phút]

Chuyển đến khóa học video UX ↬

Bit thứ tám

Máy in từ xa và người đánh dấu cổ phiếu khá vui khi gửi 7 bit thông tin cho nhau. Nhưng các bộ vi xử lý mới của thập niên 1970 thích làm việc với công suất 2. Họ có thể xử lý 8 bit cùng một lúc và do đó đã sử dụng 8 bit [còn gọi là byte hoặc octet] để lưu trữ từng ký tự, đưa ra 256 giá trị có thể

Một ký tự 8 bit có thể lưu trữ một số lên tới 255, nhưng ASCII chỉ gán tối đa 127. Các giá trị khác từ 128 đến 255 là dự phòng. Ban đầu, máy tính cá nhân của IBM sử dụng các khe cắm dự phòng để thể hiện các chữ cái có dấu, các biểu tượng và hình dạng khác nhau và một số chữ cái Hy Lạp. Chẳng hạn, số 200 là góc dưới bên trái của hộp. ╚, và 224 là chữ cái Hy Lạp alpha viết thường. α. Cách mã hóa các chữ cái này về sau được đặt tên là mã trang 437

Tuy nhiên, không giống như ASCII, các ký tự 128-255 chưa bao giờ được tiêu chuẩn hóa và nhiều quốc gia bắt đầu sử dụng các vị trí dự phòng cho bảng chữ cái của riêng họ. Không phải ai cũng đồng ý rằng 224 sẽ hiển thị α, kể cả người Hy Lạp. Điều này dẫn đến việc tạo ra một số trang mã mới. Ví dụ: trong máy tính IBM của Nga sử dụng mã trang 885, 224 đại diện cho chữ cái CyrillicЯ. Và trong mã Hy Lạp trang 737, nó là chữ thường omega. ω

Ngay cả sau đó đã có sự bất đồng. Từ những năm 1980, Microsoft Windows đã giới thiệu các trang mã của riêng mình. Trong trang mã Cyrillic Windows-1251, 224 đại diện cho chữ cái Cyrillic a vàЯ ở 223

Vào cuối những năm 1990, một nỗ lực tiêu chuẩn hóa đã được thực hiện. Mười lăm bộ ký tự 8 bit khác nhau đã được tạo để bao gồm nhiều bảng chữ cái khác nhau như Cyrillic, Ả Rập, Do Thái, Thổ Nhĩ Kỳ và Thái Lan. Chúng được gọi là ISO-8859-1 cho đến ISO-8859-16 [số 12 đã bị bỏ]. Trong Cyrillic ISO-8859-5, 224 đại diện cho chữ р và Я ở vị trí 207

Vì vậy, nếu một người bạn Nga gửi cho bạn một tài liệu, bạn thực sự cần biết nó sử dụng mã trang nào. Bản thân tài liệu chỉ là một dãy số. Ký tự 224 có thể là Я, a hoặc р. Khi xem bằng trang mã sai, nó sẽ trông giống như một loạt các chữ cái và ký hiệu bị xáo trộn

[Tình hình không tệ như vậy khi xem các trang Web - vì trình duyệt Web thường có thể phát hiện bộ ký tự của trang dựa trên phân tích tần suất và các kỹ thuật tương tự khác. Nhưng đây là cảm giác an toàn sai lầm — họ có thể và đã hiểu sai. ]

Tự mình thử

Các trang mã còn được gọi là bộ ký tự. Bạn có thể tự khám phá các bộ ký tự này, nhưng lần này bạn phải sử dụng PHP hoặc ngôn ngữ phía máy chủ tương tự [đại khái là vì ký tự cần phải có trong trang trước khi đến trình duyệt]. Lưu những dòng này trong một tệp PHP và tải nó lên máy chủ của bạn






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


Điều này sẽ hiển thị một bảng như thế này


Bộ ký tự Cyrillic ISO-8859-5 được xem trong Firefox

Hàm PHP

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
0 thực hiện tương tự như hàm





p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


9 của Javascript. Ví dụ
HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
1 nhúng số 224 vào trang Web trước khi gửi tới trình duyệt. Như chúng ta đã thấy ở trên, 224 có thể có nhiều nghĩa khác nhau. Vì vậy, trình duyệt cần biết bộ ký tự nào sẽ được sử dụng để hiển thị 224. Đó là những gì dòng đầu tiên ở trên là dành cho. Nó yêu cầu trình duyệt sử dụng bộ ký tự Cyrillic ISO-8858-5

Nếu bạn loại trừ dòng

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
2, thì nó sẽ hiển thị bằng cách sử dụng mặc định của trình duyệt. Ở các quốc gia có bảng chữ cái dựa trên tiếng Latinh [như Vương quốc Anh và Hoa Kỳ], đây có thể là ISO-8859-1, trong trường hợp đó 224 là một dấu trọng âm. một. Hãy thử thay đổi dòng này thành ISO-8859-7 hoặc Windows-1251 và làm mới trang. Bạn cũng có thể ghi đè bộ ký tự trong trình duyệt. Trong Firefox, đi tới Xem> Mã hóa ký tự. Trao đổi giữa một số để xem nó có tác dụng gì. Nếu bạn cố gắng hiển thị nhiều hơn 256 ký tự, trình tự sẽ lặp lại

Tóm tắt khoảng năm 1990

Đây là tình hình vào khoảng năm 1990. Tài liệu có thể được viết, lưu và trao đổi bằng nhiều ngôn ngữ, nhưng bạn cần biết chúng sử dụng bộ ký tự nào. Cũng không có cách nào dễ dàng để sử dụng hai hoặc nhiều bảng chữ cái không phải tiếng Anh trong cùng một tài liệu và bảng chữ cái có hơn 256 ký tự như tiếng Trung và tiếng Nhật phải sử dụng các hệ thống hoàn toàn khác nhau.

Cuối cùng thì Internet cũng đến. Quốc tế hóa và toàn cầu hóa sắp làm cho vấn đề này trở nên lớn hơn nhiều. Cần có tiêu chuẩn mới

Unicode để giải cứu

Bắt đầu từ cuối những năm 1980, một tiêu chuẩn mới đã được đề xuất – một tiêu chuẩn sẽ gán một số duy nhất [chính thức được gọi là điểm mã] cho mọi chữ cái trong mọi ngôn ngữ, một tiêu chuẩn sẽ có hơn 256 vị trí. Nó được gọi là Unicode. Nó hiện đang ở phiên bản 6. 1 và bao gồm hơn 110.000 điểm mã. Nếu bạn có vài giờ rảnh rỗi, bạn có thể xem tất cả chúng trong quá khứ

128 điểm mã Unicode đầu tiên giống như ASCII. Phạm vi 128-255 chứa các ký hiệu tiền tệ và các dấu hiệu phổ biến khác cũng như các ký tự có dấu [còn gọi là các ký tự có dấu phụ] và phần lớn trong số đó được vay mượn ISO-8859-1. Sau 256 còn nhiều ký tự có dấu nữa. Sau năm 880, nó chuyển sang các chữ cái Hy Lạp, sau đó là chữ cái Cyrillic, tiếng Do Thái, tiếng Ả Rập, chữ Ấn Độ và tiếng Thái. Tiếng Trung, tiếng Nhật và tiếng Hàn bắt đầu từ năm 11904 với nhiều người khác ở giữa

Điều này thật tuyệt – không còn mơ hồ nữa – mỗi chữ cái được biểu thị bằng một số duy nhất của chính nó. Cyrillic Я luôn là 1071 và Hy Lạp α luôn là 945. 224 luôn à, còn H vẫn là 72. Lưu ý rằng các điểm mã Unicode này được viết chính thức ở dạng thập lục phân trước U+. Vì vậy mã Unicode điểm H thường được viết là U+0048 chứ không phải 72 [để đổi từ thập lục phân sang thập phân. 4*16+8=72]

Vấn đề chính là có hơn 256 người trong số họ. Các ký tự sẽ không còn phù hợp với 8 bit. Tuy nhiên Unicode không phải là một bộ ký tự hoặc trang mã. Chính thức thì đó không phải là vấn đề của Unicode Consortium. Họ chỉ nghĩ ra ý tưởng và để người khác sắp xếp việc thực hiện. Điều đó sẽ được thảo luận trong hai phần tiếp theo

Unicode bên trong trình duyệt

Unicode không vừa với 8 bit, thậm chí không khớp với 16 bit. Mặc dù chỉ có 110.116 điểm mã được sử dụng nhưng nó có khả năng xác định tới 1.114.112 trong số đó, yêu cầu 21 bit

Tuy nhiên, máy tính đã phát triển từ những năm 1970. Bộ vi xử lý 8 bit hơi lỗi thời. Các máy tính mới hiện có bộ xử lý 64 bit, vậy tại sao chúng ta không thể chuyển từ ký tự 8 bit sang ký tự 32 bit hoặc 64 bit?

câu trả lời đầu tiên là. chúng ta có thể

Rất nhiều phần mềm được viết bằng C hoặc C++, hỗ trợ một “ký tự rộng”. Đây là ký tự 32 bit có tên là

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
3. Nó là phần mở rộng của loại 8 bit
HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
4 của C. Trong nội bộ, các trình duyệt Web hiện đại sử dụng các ký tự rộng này [hoặc một cái gì đó tương tự] và về mặt lý thuyết có thể xử lý khá dễ dàng với hơn 4 tỷ ký tự riêng biệt. Điều này là rất nhiều cho Unicode. Vì vậy - trong nội bộ, các trình duyệt Web hiện đại sử dụng Unicode

Tự mình thử

Mã Javascript bên dưới tương tự như mã ASCII ở trên, ngoại trừ nó tăng lên một số cao hơn nhiều. Đối với mỗi số, nó báo cho trình duyệt hiển thị điểm mã Unicode tương ứng

________số 8

Nó sẽ xuất ra một bảng như thế này


Một lựa chọn các điểm mã Unicode được xem trong Firefox

Ảnh chụp màn hình ở trên chỉ hiển thị một tập hợp con của vài nghìn điểm mã đầu tiên được Javascript tạo ra. Lựa chọn bao gồm một số ký tự Cyrillic và Ả Rập, được hiển thị từ phải sang trái

Điểm quan trọng ở đây là Javascript chạy hoàn toàn trong trình duyệt Web nơi các ký tự 32 bit hoàn toàn chấp nhận được. Hàm Javascript

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
5 xuất điểm mã Unicode 1071 là chữ cái Я

Tương tự, nếu bạn đặt thực thể HTML

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
6 vào một trang HTML, một trình duyệt Web hiện đại sẽ hiển thị Я. Các thực thể HTML số cũng đề cập đến Unicode

Mặt khác, hàm PHP

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
7 sẽ tạo ra dấu gạch chéo lên / vì hàm
HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
0 chỉ xử lý các số 8 bit lên đến 256 và lặp lại chính nó sau đó, và 1071%256=47 là dấu / kể từ những năm 1960

UTF-8 để giải cứu

Vì vậy, nếu các trình duyệt có thể xử lý Unicode bằng các ký tự 32 bit, thì vấn đề nằm ở đâu?

Vấn đề vẫn còn bởi vì

  1. Rất nhiều phần mềm và giao thức hiện có gửi/nhận và đọc/ghi các ký tự 8 bit
  2. Sử dụng 32 bit để gửi/lưu trữ văn bản tiếng Anh sẽ tăng gấp bốn lần lượng băng thông/không gian cần thiết

Mặc dù các trình duyệt có thể xử lý Unicode bên trong, nhưng bạn vẫn phải lấy dữ liệu từ máy chủ Web đến trình duyệt Web và ngược lại, và bạn cần lưu nó vào một tệp hoặc cơ sở dữ liệu ở đâu đó. Vì vậy, bạn vẫn cần một cách để làm cho 110.000 điểm mã Unicode vừa với 8 bit

Đã có một số nỗ lực để giải quyết vấn đề này như UCS2 và UTF-16. Nhưng người chiến thắng trong những năm gần đây là UTF-8, viết tắt của Universal Character Set Transformation Format 8 bit

UTF-8 là một thông minh. Nó hoạt động hơi giống phím Shift trên bàn phím của bạn. Thông thường khi bạn nhấn H trên bàn phím, chữ “h” thường xuất hiện trên màn hình. Nhưng nếu bạn nhấn Shift trước, chữ H viết hoa sẽ xuất hiện

UTF-8 coi các số 0-127 là ASCII, 192-247 là phím Shift và 128-192 là phím được dịch chuyển. Chẳng hạn, các ký tự 208 và 209 chuyển bạn sang phạm vi Cyrillic. 208 theo sau bởi 175 là ký tự 1071, Cyrillic Я. Phép tính chính xác là [208%32]*64 + [175%64] = 1071. Các ký tự 224-239 giống như một ca kép. 226 theo sau là 190 và sau đó 128 là ký tự 12160. ⾀. 240 trở lên là ca ba

Do đó, UTF-8 là mã hóa có độ rộng thay đổi nhiều byte. Nhiều byte vì một ký tự đơn lẻ như Я mất nhiều hơn một byte để chỉ định nó. Độ rộng thay đổi vì một số ký tự như H chỉ chiếm 1 byte và một số lên tới 4

Hay nhất là nó tương thích ngược với ASCII. Không giống như một số giải pháp được đề xuất khác, bất kỳ tài liệu nào chỉ được viết bằng ASCII, chỉ sử dụng các ký tự 0-127, cũng hoàn toàn hợp lệ UTF-8 — giúp tiết kiệm băng thông và rắc rối

Tự mình thử

Đây là một thử nghiệm khác. PHP nhúng 6 số nói trên vào trang HTML. 72, 208, 175, 226, 190, 128. Trình duyệt diễn giải các số đó dưới dạng UTF-8 và chuyển đổi nội bộ chúng thành các điểm mã Unicode. Sau đó, Javascript xuất các giá trị Unicode. Hãy thử thay đổi bộ ký tự từ UTF-8 thành ISO-8859-1 và xem điều gì sẽ xảy ra

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
2

Nếu bạn đang vội, nó sẽ như thế này


Chuỗi số ở trên được hiển thị bằng bộ ký tự UTF-8


Cùng một dãy số được hiển thị bằng bộ ký tự ISO-8859-1

Nếu bạn hiển thị trang bằng bộ ký tự UTF-8, bạn sẽ chỉ thấy 3 ký tự. HЯ⾀. Nếu bạn hiển thị nó bằng bộ ký tự ISO-8859-1, bạn sẽ thấy sáu ký tự riêng biệt. Hï⾀. Đây là những gì đang xảy ra

  1. Trên máy chủ Web của bạn, PHP đang nhúng các số 72, 208, 175, 226, 190 và 128 vào một trang Web
  2. Trang Web lướt qua Internet từ máy chủ Web đến trình duyệt Web của bạn
  3. Trình duyệt nhận những con số đó và diễn giải chúng theo bộ ký tự
  4. Trình duyệt bên trong đại diện cho các ký tự sử dụng các giá trị Unicode của chúng
  5. Javascript xuất ra các giá trị Unicode tương ứng

Lưu ý rằng khi được xem là ISO-8859-1, 5 số đầu tiên giống nhau [72, 208, 175, 226, 190] như các điểm mã Unicode của chúng. Điều này là do Unicode mượn rất nhiều từ ISO-8859-1 trong phạm vi đó. Tuy nhiên, số cuối cùng, ký hiệu euro €, lại khác. Nó nằm ở vị trí 128 trong ISO-8859-1 và có giá trị Unicode 8364

Tóm tắt khoảng năm 2003

UTF-8 đang trở thành bộ ký tự quốc tế phổ biến nhất trên Internet, thay thế các bộ ký tự một byte cũ hơn như ISO-8859-5. Khi bạn xem hoặc gửi một tài liệu không phải tiếng Anh, bạn vẫn cần biết nó sử dụng bộ ký tự nào. Để có khả năng tương tác rộng nhất, quản trị viên website cần đảm bảo tất cả các trang web của họ sử dụng bộ ký tự UTF-8

Có lẽ Ð trông quen thuộc — đôi khi nó sẽ hiển thị nếu bạn cố xem các tài liệu UTF-8 của Nga. Phần tiếp theo mô tả cách các bộ ký tự bị nhầm lẫn và cuối cùng lưu trữ sai mọi thứ trong cơ sở dữ liệu

Rất nhiều vấn đề

Miễn là mọi người đang nói UTF-8, tất cả điều này sẽ hoạt động trơn tru. Nếu không, thì các ký tự có thể bị xáo trộn. Để giải thích cách này, hãy tưởng tượng một tương tác điển hình trên trang web, chẳng hạn như người dùng đưa ra nhận xét về bài đăng trên blog

  1. Một trang Web hiển thị một mẫu bình luận
  2. Người dùng nhập nhận xét và gửi
  3. Nhận xét được gửi trở lại máy chủ và được lưu trong cơ sở dữ liệu
  4. Nhận xét sau đó được lấy từ cơ sở dữ liệu và hiển thị trên trang Web

Quá trình đơn giản này có thể sai theo nhiều cách và tạo ra các loại vấn đề sau

Thực thể HTML

Giả vờ một lúc rằng bạn không biết gì về bộ ký tự - xóa 30 phút qua khỏi bộ nhớ của bạn. Biểu mẫu trên blog của bạn có thể sẽ tự hiển thị bằng bộ ký tự ISO-8859-1. Bộ chữ này không biết tiếng Nga hay tiếng Thái hay tiếng Trung và chỉ biết một chút tiếng Hy Lạp. Nếu bạn cố gắng sao chép và dán bất kỳ biểu mẫu nào vào biểu mẫu và nhấn Gửi, một trình duyệt hiện đại sẽ cố gắng chuyển đổi nó thành các thực thể số HTML như

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
6 cho Я

Đó là những gì sẽ được lưu trong cơ sở dữ liệu của bạn và đó là những gì sẽ được xuất ra khi nhận xét được hiển thị — có nghĩa là nó sẽ hiển thị tốt trên một trang Web, nhưng gây ra sự cố khi bạn cố xuất nó thành PDF hoặc email hoặc chạy văn bản

nhân vật bối rối

Sẽ thế nào nếu bạn điều hành một trang web tiếng Nga và bạn chưa chỉ định một bộ ký tự trong trang Web của mình? . Để nói “xin chào”, họ có thể gõ Привет. Khi người dùng nhấn Gửi , các ký tự được mã hóa theo bộ ký tự của trang gửi. Trong trường hợp này, Привет được mã hóa thành các số 191, 224, 216, 210, 213 và 226. Những con số đó sẽ được gửi qua Internet đến máy chủ và được lưu như vậy vào cơ sở dữ liệu.

Nếu ai đó sau này xem nhận xét đó bằng ISO-8859-5, họ sẽ thấy văn bản chính xác. Nhưng nếu họ xem bằng bộ ký tự tiếng Nga khác như Windows-1251, họ sẽ thấy їаШТХв. Nó vẫn là tiếng Nga, nhưng vô nghĩa

Ký tự có trọng âm với nhiều nguyên âm

Nếu ai đó xem cùng một nhận xét bằng ISO-8859-1, họ sẽ thấy ¿àØÒÕâ thay vì Привет. Một cụm từ dài hơn như Я тоже рада Вас видеть [“rất vui được gặp bạn” theo cách trang trọng dành cho nữ], được gửi dưới dạng ISO-8859-5, sẽ hiển thị trong ISO-8859-1 dưới dạng Ï âÞÖÕ àÐÔÐ. Có vẻ như vậy vì phạm vi 128-255 của ISO-8859-1 chứa rất nhiều nguyên âm có trọng âm

Vì vậy, nếu bạn thấy kiểu mẫu này, thì có thể là do văn bản đã được nhập trong một bộ ký tự byte đơn [một trong các bộ ký tự ISO-8859 hoặc Windows] và đang được hiển thị dưới dạng ISO-8859-1. Để sửa văn bản, bạn cần tìm ra bộ ký tự được nhập dưới dạng và gửi lại dưới dạng UTF-8

Nhân vật có dấu xen kẽ

Nếu người dùng gửi nhận xét bằng UTF-8 thì sao? . 208⁄159, 209⁄128, 208⁄184, 208⁄178, 208⁄181 và 209⁄130. Nếu bạn đã xem nó trong ISO-8859-1 thì nó sẽ giống như. Привет

Lưu ý rằng mọi ký tự khác là Ð hoặc Ñ. Các ký tự đó là số 208 và 209 và chúng yêu cầu UTF-8 chuyển sang phạm vi Cyrillic. Vì vậy, nếu bạn thấy nhiều Ð và Ñ, bạn có thể cho rằng mình đang xem văn bản tiếng Nga được nhập bằng UTF-8, được xem dưới dạng ISO-8859-1. Tương tự, tiếng Hy Lạp sẽ có nhiều Î và Ï, 206 và 207. Và tiếng Do Thái có xen kẽ ×, số 215

Nguyên âm trước bảng Anh và Dấu hiệu bản quyền

Một vấn đề rất phổ biến ở Vương quốc Anh là ký hiệu tiền tệ £ được chuyển thành  £. Đây chính xác là vấn đề tương tự như trên với một sự trùng hợp ngẫu nhiên được đưa vào để thêm nhầm lẫn. Biểu tượng £ có giá trị Unicode và ISO-8859-1 là 163. Nhớ lại rằng trong UTF-8, bất kỳ ký tự nào trên 127 đều được biểu thị bằng một chuỗi gồm hai số trở lên. Trong trường hợp này, chuỗi UTF-8 là 194⁄163. Về mặt toán học, điều này là do [194%32]*64 + [163%64] = 163

Về mặt trực quan, điều đó có nghĩa là nếu bạn xem chuỗi UTF-8 bằng ISO-8859-1, thì có vẻ như nó nhận được  là ký tự 194 trong ISO-8859-1. Điều tương tự cũng xảy ra với tất cả các điểm mã Unicode 161-191, bao gồm © và ® và ¥

Vì vậy, nếu £ hoặc © của bạn đột nhiên kế thừa một Â, đó là do chúng được nhập dưới dạng UTF-8

Dấu hỏi kim cương đen

Làm thế nào về cách khác xung quanh? . 191, 224, v.v. Sau đó, nếu bạn cố xem đây là UTF-8, bạn có thể thấy rất nhiều dấu chấm hỏi bên trong viên kim cương đen. �. Trình duyệt hiển thị những thứ này khi nó không thể hiểu được những con số mà nó đang đọc

UTF-8 tự đồng bộ hóa. Không giống như các mã hóa ký tự nhiều byte khác, bạn luôn biết mình đang ở đâu với UTF-8. Nếu bạn thấy số 192-247, bạn biết bạn đang ở đầu chuỗi nhiều byte. Nếu bạn nhìn thấy 128-191, bạn biết bạn đang ở giữa một. Không có nguy cơ thiếu số đầu tiên và cắt xén phần còn lại của văn bản

Điều này có nghĩa là trong UTF-8, chuỗi 191 theo sau là 224 sẽ không bao giờ xảy ra một cách tự nhiên, vì vậy trình duyệt không biết phải làm gì với nó và thay vào đó hiển thị ��

Điều này cũng có thể gây ra các sự cố liên quan đến £ và ©. £50 trong ISO-8859-1 là các số 163, 53 và 48. 53 và 48 không gây ra vấn đề gì, nhưng trong UTF-8, 163 không bao giờ có thể tự xảy ra, vì vậy giá trị này sẽ hiển thị là �50. Tương tự, nếu bạn thấy �2012, có thể là do ©2012 được nhập dưới dạng ISO-8859-1 nhưng đang được hiển thị dưới dạng UTF-8

Khoảng trống, Dấu chấm hỏi và Hộp

Ngay cả khi chúng được cập nhật hoàn toàn với UTF-8 và Unicode, trình duyệt vẫn có thể không biết cách hiển thị một ký tự. Một vài ký tự ASCII đầu tiên 1-31 hầu hết là các chuỗi điều khiển cho máy in từ xa [những thứ như Xác nhận và Dừng]. Nếu bạn cố hiển thị chúng, trình duyệt có thể hiển thị dấu ?

Ngoài ra, Unicode xác định hơn 110.000 ký tự. Trình duyệt của bạn có thể không có đúng phông chữ để hiển thị tất cả chúng. Một số ký tự khó hiểu hơn cũng có thể được hiển thị dưới dạng ? . Trong các trình duyệt cũ hơn, ngay cả các ký tự không phải tiếng Anh khá phổ biến cũng có thể hiển thị dưới dạng hộp

Các trình duyệt cũ hơn cũng có thể hoạt động khác đối với một số vấn đề ở trên, hiển thị ?

cơ sở dữ liệu

Cuộc thảo luận ở trên đã tránh được bước giữa trong quy trình - lưu dữ liệu vào cơ sở dữ liệu. Các cơ sở dữ liệu như MySQL cũng có thể chỉ định một bộ ký tự cho cơ sở dữ liệu, bảng hoặc cột. Nhưng điều ít quan trọng hơn là bộ ký tự của các trang Web

Khi lưu và truy xuất dữ liệu, MySQL chỉ xử lý các số. Nếu bạn bảo nó lưu số 163 thì nó sẽ. Nếu bạn cho nó 208⁄159, nó sẽ lưu hai số đó. Và khi bạn truy xuất dữ liệu, bạn sẽ nhận lại được hai số giống nhau

Bộ ký tự trở nên quan trọng hơn khi bạn sử dụng các hàm cơ sở dữ liệu để so sánh, chuyển đổi và đo lường dữ liệu. Ví dụ: ______20 của một trường có thể phụ thuộc vào bộ ký tự của nó, cũng như so sánh chuỗi sử dụng ______21 và






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


2. Phương pháp được sử dụng để so sánh các chuỗi được gọi là đối chiếu

Bộ ký tự và đối chiếu trong MySQL là một chủ đề chuyên sâu. Nó không chỉ đơn giản là trường hợp thay đổi bộ ký tự của bảng thành UTF-8. Có thêm các lệnh SQL cần tính đến để đảm bảo dữ liệu đi vào và đi ra đúng định dạng

Tự mình thử

Mã PHP và Javascript sau đây cho phép bạn thử nghiệm với tất cả các vấn đề này. Bạn có thể chỉ định bộ ký tự nào được sử dụng để nhập và xuất văn bản và bạn cũng có thể xem trình duyệt nghĩ gì về nó

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
7

Đây là một ví dụ về mã đang hoạt động. Các số ở trên cùng là các giá trị số của từng ký tự và biểu diễn của chúng [khi được xem riêng lẻ] trong bộ ký tự hiện tại


Ví dụ về nhập và xuất trong các bộ ký tự khác nhau. Điều này cho thấy dấu £ chuyển thành dấu � trong Google Chrome

Trang trên hiển thị các bộ ký tự trước đó, hiện tại và tương lai. Bạn có thể sử dụng mã này để xem nhanh văn bản có thể bị xáo trộn như thế nào. Ví dụ: nếu bạn nhấn Gửi một lần nữa ở trên, � có điểm mã Unicode 65533 là 239/191/189 trong UTF-8 và sẽ được hiển thị là �50 trong ISO-8859-1. Vì vậy, nếu bạn từng thấy các ký hiệu £ biến thành �, thì đó có thể là cách họ đã thực hiện

Lưu ý rằng hộp chọn ở dưới cùng sẽ thay đổi lại thành ISO-8859-1 mỗi lần

Một cách giải quyết

Tất cả các sự cố mã hóa ở trên là do văn bản được gửi bằng một bộ ký tự và được xem ở một bộ ký tự khác. Giải pháp là đảm bảo rằng mọi trang trên trang web của bạn đều sử dụng UTF-8. Bạn có thể làm điều này với một trong những dòng này ngay sau thẻ






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


3

HELLO
HELLO
document.write ["HELLO"];
document.write [String.fromCharCode [72,69,76,76,79]];
9

Nó phải là một trong những điều đầu tiên trong trang Web của bạn, vì nó sẽ khiến trình duyệt nhìn lại trang theo một cách hoàn toàn mới. Để có tốc độ và hiệu quả, nó nên làm điều này càng sớm càng tốt

Bạn cũng có thể chỉ định UTF-8 trong các bảng MySQL của mình, tuy nhiên để sử dụng đầy đủ tính năng này, bạn sẽ cần tìm hiểu sâu hơn

Lưu ý rằng người dùng vẫn có thể ghi đè bộ ký tự trong trình duyệt của họ. Điều này rất hiếm, nhưng không có nghĩa là giải pháp này không đảm bảo sẽ hoạt động. Để an toàn hơn, bạn có thể thực hiện kiểm tra back-end để đảm bảo dữ liệu đến đúng định dạng

Trang web hiện có

Nếu trang web của bạn đã thu thập văn bản bằng nhiều ngôn ngữ, thì bạn cũng sẽ cần chuyển đổi dữ liệu hiện có của mình thành UTF-8. Nếu không có nhiều, bạn có thể sử dụng trang PHP như trang trên để tìm ra bộ ký tự gốc và sử dụng trình duyệt để chuyển đổi dữ liệu thành UTF-8

Nếu bạn có nhiều dữ liệu trong các bộ ký tự khác nhau, trước tiên bạn cần phát hiện bộ ký tự đó rồi chuyển đổi nó. Trong PHP, bạn có thể sử dụng






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


4 để phát hiện và





p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


5 để chuyển đổi. Đọc các nhận xét về





p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


4, có vẻ như đây là một chức năng khá phức tạp, vì vậy hãy thử nghiệm để đảm bảo rằng bạn đang sử dụng nó đúng cách và nhận được kết quả phù hợp

Một chức năng có khả năng gây hiểu lầm là






p {float: left; padding: 0 15px; margin: 0; font-size: 80%;}


7. Nó biến UTF-8 thành ISO-8859-1. Bất kỳ ký tự nào không có sẵn trong ISO-8859-1 [như Cyrillic, Greek, Thai, v.v.] sẽ được chuyển thành dấu chấm hỏi. Nó gây hiểu lầm bởi vì bạn có thể đã mong đợi nhiều hơn từ nó, nhưng nó làm tốt nhất có thể

Bản tóm tắt

Bài viết này chủ yếu dựa vào các con số và đã cố gắng hết sức cẩn thận. Hy vọng rằng nó đã cung cấp sự hiểu biết thấu đáo về các bộ ký tự, Unicode, UTF-8 và các vấn đề khác nhau có thể phát sinh. Đạo đức của câu chuyện là

Cách đặt UTF

PHP UTF-8 Encoding – sửa đổi php của bạn. Điều đầu tiên bạn cần làm là sửa đổi php của bạn. ini để sử dụng UTF-8 làm bộ ký tự mặc định. default_charset = "utf-8"; [Lưu ý. Sau đó, bạn có thể sử dụng phpinfo[] để xác minh rằng điều này đã được đặt đúng cách. ]

Cách giải mã UTF

Hàm utf8_decode[] là một hàm sẵn có trong PHP được sử dụng để giải mã chuỗi UTF-8 thành ISO-8859- . Hàm này giải mã trở lại chuỗi đã mã hóa được mã hóa bằng hàm utf8_encode[]. Tham số. Hàm này chấp nhận tham số duy nhất $string được yêu cầu.

Cách chuyển đổi ASCII sang UTF

Nếu chúng tôi biết rằng mã hóa hiện tại là ASCII, hàm 'iconv' có thể được sử dụng để chuyển đổi ASCII thành UTF-8 . Chuỗi ban đầu có thể được chuyển thành tham số cho hàm iconv để mã hóa nó thành UTF-8.

Làm cách nào để khắc phục sự cố mã hóa ký tự trong PHP?

Chỉ cần thêm mã hóa bộ ký tự mong muốn của bạn vào. htaccess và đặt nó vào thư mục gốc www của bạn. Nếu bạn muốn mân mê các chuỗi ký tự và sử dụng mã php của mình cho điều đó - đó là một câu chuyện khác. Đối chiếu cơ sở dữ liệu tất nhiên phải chính xác

Chủ Đề