Làm cách nào để đặt bộ ký tự trong PHP?

Dự án PHP của bạn có thể liên quan đến việc xử lý nhiều dữ liệu đến từ những nơi khác nhau, chẳng hạn như cơ sở dữ liệu hoặc API và mỗi khi bạn cần xử lý dữ liệu đó, bạn có thể gặp sự cố mã hóa

Bài viết này sẽ giúp bạn chuẩn bị khi điều đó xảy ra và hiểu rõ hơn những gì đang diễn ra đằng sau hậu trường

Giới thiệu về mã hóa

Mã hóa là cốt lõi của bất kỳ ngôn ngữ lập trình nào và thông thường, chúng tôi coi đó là điều hiển nhiên. Mọi thứ đều hoạt động cho đến khi nó không hoạt động và chúng tôi gặp lỗi xấu, chẳng hạn như "Ký tự UTF-8 không đúng định dạng, có thể được mã hóa không chính xác"

Để tìm hiểu lý do tại sao một cái gì đó trong mã hóa có thể không hoạt động, trước tiên chúng ta cần hiểu ý nghĩa của mã hóa và cách thức hoạt động của mã hóa

mã Morse

Mã Morse là một cách tuyệt vời để giải thích mã hóa là gì. Khi nó được phát triển, đây là một trong những lần đầu tiên trong lịch sử một tin nhắn có thể được mã hóa, gửi đi, sau đó được giải mã và hiểu bởi người nhận

Nếu chúng tôi sử dụng mã Morse để truyền tin nhắn, trước tiên chúng tôi cần chuyển tin nhắn của mình thành dấu chấm và dấu gạch ngang (còn gọi là dấu ngắn và dấu dài), hai tín hiệu duy nhất có sẵn trong phương pháp này. Khi tin nhắn đến đích, người nhận cần chuyển đổi nó từ mã Morse sang tiếng Anh. Nó trông giống như thế này

"Hi" -> Encode("Hi") -> Send("... ..") -> Decode("... ..") -> "Hi"

Hệ thống này được phát minh vào khoảng năm 1837 và mọi người đã mã hóa và giải mã các tin nhắn theo cách thủ công. Ví dụ,

  • S được mã hóa thành. (ba dấu ngắn)
  • T as - (một dấu dài)
  • Ucas. - (hai dấu ngắn và một dấu dài)

Đây là mã hóa nhà điều hành đài phát thanh bằng mã Morse

Làm cách nào để đặt bộ ký tự trong PHP?

Trên tàu Titanic, mã Morse được sử dụng để gửi và nhận tin nhắn, kể cả tin nhắn cuối cùng yêu cầu trợ giúp ("CQD" là cuộc gọi cấp cứu)

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic

Trong mã hóa máy tính, máy tính mã hóa và giải mã các ký tự theo cách rất giống nhau. Sự khác biệt duy nhất là thay vì dấu chấm và dấu gạch ngang, chúng ta có các số 1 và 0 trong mã nhị phân

Nhị phân và ký tự

Như bạn có thể biết, máy tính chỉ hiểu mã nhị phân trong 1 và 0, vì vậy không có thứ gọi là ký tự. Nó được diễn giải bởi phần mềm bạn sử dụng

Để mã hóa và giải mã các ký tự thành 1 và 0, chúng tôi cần một cách tiêu chuẩn để thực hiện việc đó sao cho nếu tôi gửi cho bạn một loạt các ký tự 1 và 0, bạn sẽ diễn giải chúng (giải mã chúng) giống như cách tôi đã mã hóa chúng

Hãy tưởng tượng điều gì sẽ xảy ra nếu mỗi máy tính dịch mã nhị phân thành các ký tự và ngược lại theo cách riêng của nó. Nếu bạn đã gửi tin nhắn cho một người bạn, họ không thể xem tin nhắn thực của bạn vì đối với máy tính của họ, số 1 và số 0 của bạn có ý nghĩa khác. Đây là lý do tại sao chúng ta cần thống nhất về cách chúng ta chuyển đổi các ký tự thành mã nhị phân và ngược lại;

Tiêu chuẩn

Các tiêu chuẩn mã hóa có một lịch sử lâu dài. Chúng ta không cần phải khám phá đầy đủ lịch sử ở đây, nhưng điều cần thiết là phải biết hai cột mốc quan trọng xác định cách máy tính có thể sử dụng mã hóa, đặc biệt là với sự ra đời của Internet

ASCII

ASCII, được phát triển vào năm 1963, là một trong những tiêu chuẩn đầu tiên và quan trọng nhất, và nó vẫn đang được sử dụng (chúng tôi sẽ giải thích điều này sau). ASCII là viết tắt của Mã tiêu chuẩn Mỹ để trao đổi thông tin. Phần "Mỹ" rất phù hợp vì nó chỉ có thể mã hóa 127 ký tự trong phiên bản đầu tiên, bao gồm bảng chữ cái tiếng Anh và một số ký hiệu cơ bản, chẳng hạn như "?"

Đây là bảng đầy đủ

Làm cách nào để đặt bộ ký tự trong PHP?
Nguồn

Máy tính không thể thực sự sử dụng số. Như chúng ta đã biết, máy tính chỉ hiểu mã nhị phân, 1 và 0, vì vậy những giá trị này sau đó được mã hóa thành nhị phân

Ví dụ: "K" là 75 trong ASCII, vì vậy chúng tôi có thể chuyển đổi nó thành nhị phân bằng cách chia 75 cho 2 và tiếp tục cho đến khi chúng tôi nhận được 0. Nếu phép chia không chính xác, chúng tôi thêm 1 làm phần còn lại

75 / 2 = 37 + 1
37 / 2 = 18 + 1
18 / 2 =  9 + 0
9 / 2 =   4 + 1
4 / 2 =   2 + 0
2 / 2 =   1 + 0
1 / 2 =   0 + 1

Bây giờ, chúng tôi trích xuất "phần còn lại" và đặt chúng theo thứ tự ngược lại

1101001 => 1001011

Vì vậy, trong ASCII, "K" được mã hóa thành 1001011 ở dạng nhị phân

Vấn đề chính với ASCII là nó không bao gồm các ngôn ngữ khác. Nếu bạn muốn sử dụng máy tính của mình bằng tiếng Nga hoặc tiếng Nhật, bạn cần một tiêu chuẩn mã hóa khác, tiêu chuẩn này sẽ không tương thích với ASCII

Bạn đã bao giờ nhìn thấy các biểu tượng như "???" . Chương trình cố gắng diễn giải các ký tự bằng một phương thức mã hóa, nhưng chúng không thể hiện bất kỳ điều gì có ý nghĩa vì nó được tạo bằng một phương thức mã hóa khác. Đây là lý do tại sao chúng tôi cần bước đột phá lớn thứ hai, Unicode và UTF-8

bảng chữ cái

Mục tiêu khi phát triển Unicode là có một cách duy nhất để chuyển đổi bất kỳ ký tự hoặc biểu tượng nào trong bất kỳ ngôn ngữ nào trên thế giới thành một số duy nhất, không có gì khác

Nếu bạn chuyển sang unicode. org, bạn có thể tra cứu số cho bất kỳ ký tự nào, kể cả biểu tượng cảm xúc

Ví dụ: "A" là 65, "Y" là 121 và 🍐 là 127824

Vấn đề là máy tính chỉ có thể lưu trữ và xử lý mã nhị phân, vì vậy chúng ta vẫn cần chuyển đổi các số này. Nhiều hệ thống mã hóa có thể đạt được kỳ tích này, nhưng chúng tôi sẽ tập trung vào hệ thống mã hóa phổ biến nhất hiện nay. UTF-8

UTF-8

UTF-8 làm cho tiêu chuẩn Unicode có thể sử dụng được bằng cách cung cấp cho chúng tôi một cách hiệu quả để chuyển đổi số thành mã nhị phân. Trong nhiều trường hợp, đó là mã hóa mặc định cho nhiều ngôn ngữ lập trình và trang web vì hai lý do quan trọng

  • UTF-8 (và Unicode) tương thích với ASCII. Khi UTF-8 được tạo ra vào năm 1993, rất nhiều dữ liệu ở dạng ASCII, vì vậy bằng cách làm cho UTF-8 tương thích với nó, mọi người không cần phải chuyển đổi dữ liệu trước khi sử dụng nó. Về cơ bản, một tệp trong ASCII có thể được coi là UTF-8 và nó chỉ hoạt động
  • UTF-8 hiệu quả. Khi chúng tôi lưu trữ hoặc gửi ký tự qua máy tính, điều quan trọng là chúng không chiếm quá nhiều dung lượng. Ai muốn có tệp 1 GB khi bạn có thể có tệp 256 MB?

Hãy khám phá thêm một chút về cách UTF-8 hoạt động và tại sao nó có độ dài khác nhau tùy thuộc vào ký tự được mã hóa

UTF-8 hiệu quả như thế nào?

UTF-8 lưu trữ các số theo cách động. Những cái đầu tiên trong danh sách Unicode chiếm 1 byte, nhưng những cái cuối cùng có thể chiếm tới 4 byte, vì vậy nếu bạn đang xử lý một tệp tiếng Anh, hầu hết các ký tự có thể chỉ chiếm 1 byte, giống như trong ASCII

Điều này hoạt động bằng cách bao gồm các phạm vi khác nhau trong phổ Unicode với số byte khác nhau

Ví dụ: để mã hóa bất kỳ ký tự nào trong bảng ASCII gốc (từ 0 đến 127 ở dạng thập phân), chúng ta chỉ cần 7 bit vì 2^7 = 128. Do đó, chúng tôi có thể lưu trữ mọi thứ trong 1 byte 8 bit và chúng tôi vẫn còn một byte miễn phí

Đối với phạm vi tiếp theo (từ 128 đến 2047), chúng tôi cần 11 bit vì 2^11 = 2.048, là 2 byte trong UTF-8, với một số bit cố định để cung cấp cho chúng tôi một số manh mối. Hãy nhìn vào bảng đầy đủ, và bạn sẽ thấy những gì tôi muốn nói

Làm cách nào để đặt bộ ký tự trong PHP?

Khi đọc các số 1 và 0 trong máy tính, chúng tôi không có khái niệm khoảng cách giữa chúng, vì vậy chúng tôi cần một cách để nói, "đây là loại giá trị này" hoặc "đọc x bit ngay bây giờ". Trong UTF-8, chúng tôi đạt được điều này bằng cách đặt một số số 1 và 0 một cách có chiến lược

Nếu bạn là máy tính và đọc thứ gì đó bắt đầu bằng 0 trong UTF-8, bạn biết rằng bạn chỉ cần đọc 1 byte và hiển thị đúng ký tự từ Unicode trong phạm vi 0-127

Nếu bạn gặp hai số 1 cùng nhau, điều đó có nghĩa là bạn cần đọc hai byte và bạn đang ở trong khoảng 128-2.047. Ba số 1 cùng nhau có nghĩa là bạn cần đọc ba byte

Làm cách nào để đặt bộ ký tự trong PHP?

Hãy xem một vài ví dụ

Một ký tự (chẳng hạn như "A") được dịch thành một số theo bảng Unicode khổng lồ ("65"). Sau đó, UTF-8 chuyển đổi số này thành mã nhị phân (01000001) theo mẫu mà chúng tôi đã chỉ ra

Nếu chúng tôi có một ký tự trong phạm vi cao hơn, chẳng hạn như biểu tượng cảm xúc "⚡", là 9889 theo Unicode, chúng tôi cần 3 byte

11100010 10011010 10100001

Chúng tôi cũng có thể chỉ ra cách nó hoạt động với PHP chỉ để giải trí

// We first extract the hexadecimal value of a string, like "A"
$value = unpack('H*', "A");

// Convert it now from hexadecimal to decimal (just a number)
$unicodeValue = base_convert($value[1], 16, 10); // $unicodeValue is 65

// Now we transform it from base 10 (decimal) to base 2 (binary)
echo base_convert($unicodeValue, 10, 2); // 1000001

Mã hóa trong PHP

Bây giờ chúng ta đã xem xét cách hoạt động của mã hóa nói chung, chúng ta có thể tập trung vào những phần thiết yếu mà chúng ta thường cần xử lý trong PHP

Ghi chú nhanh về các phiên bản PHP

Như bạn có thể biết, PHP đã bị mang tiếng xấu trong một thời gian khá dài. Tuy nhiên, may mắn thay, nhiều lỗi ban đầu của nó đã được sửa trong các phiên bản gần đây hơn (từ 5. X). Do đó, tôi khuyên bạn nên sử dụng phiên bản hiện đại nhất có thể để ngăn chặn bất kỳ sự cố không mong muốn nào

Trường hợp mã hóa quan trọng trong PHP

Thường có ba vị trí mã hóa quan trọng trong một chương trình

  • Các tập tin mã nguồn cho chương trình của bạn
  • Đầu vào bạn nhận được
  • Đầu ra bạn hiển thị hoặc lưu trữ trong cơ sở dữ liệu

Đặt mã hóa mặc định phù hợp

Vì UTF-8 rất phổ biến nên bạn nên đặt nó làm mã hóa mặc định cho PHP. Mã hóa này được đặt theo mặc định, nhưng nếu ai đó đã thay đổi cài đặt này, đây là cách thực hiện. Chuyển đến php của bạn. ini và thêm (hoặc cập nhật) dòng sau

default_charset = "UTF-8"

Điều gì xảy ra khi một chuỗi đến sử dụng một mã hóa khác?

phát hiện mã hóa

Ví dụ: khi chúng tôi nhận được một chuỗi từ việc đọc một tệp hoặc trong cơ sở dữ liệu, chúng tôi không biết mã hóa, vì vậy bước đầu tiên là phát hiện nó

Không phải lúc nào cũng có thể phát hiện một mã hóa cụ thể, nhưng chúng tôi có cơ hội tốt với

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
5. Để sử dụng nó, chúng tôi cần chuyển chuỗi, danh sách mã hóa hợp lệ mà bạn muốn phát hiện và liệu bạn có muốn so sánh nghiêm ngặt hay không (được khuyến nghị trong hầu hết các trường hợp)

Đây là một ví dụ về cách xác định xem một chuỗi có ở dạng UTF-8 hay không

________số 8_______

Với một danh sách mã hóa tiềm năng, chúng ta có thể chuyển một chuỗi hoặc một mảng

mb_detect_encoding($string, "JIS, eucjp-win, sjis-win", true);

$array[] = "ASCII";
$array[] = "JIS";
$array[] = "EUC-JP";
mb_detect_encoding($string, $array, true);

Hàm này sẽ trả về mã hóa ký tự được phát hiện hoặc sai nếu không thể phát hiện mã hóa

Chuyển đổi sang mã hóa khác

Sau khi rõ ràng chúng tôi đang xử lý mã hóa nào, bước tiếp theo là chuyển đổi nó thành mã hóa mặc định của chúng tôi, thường là UTF-8. Bây giờ, điều này không phải lúc nào cũng khả thi vì một số mã hóa không tương thích, nhưng chúng ta có thể thử phương pháp sau

// Convert EUC-JP to UTF-8
$string = mb_convert_encoding($stringInEUCJP, "UTF-8", "EUC-JP");

Nếu chúng tôi muốn tự động phát hiện mã hóa từ danh sách, chúng tôi có thể sử dụng như sau

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
0

Chúng tôi cũng có một chức năng khác trong PHP được gọi là

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
6, nhưng vì nó phụ thuộc vào việc triển khai cơ bản nên sử dụng
SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
7 sẽ đáng tin cậy và nhất quán hơn

Kiểm tra xem chúng tôi có mã hóa đúng không

Trước khi xử lý hoặc lưu trữ bất kỳ đầu vào nào, bạn nên kiểm tra xem chúng tôi có chuỗi ở dạng mã hóa phù hợp không. Để đạt được điều này, chúng ta có thể sử dụng

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
8 và nó sẽ trả về true hoặc false. Ví dụ: để kiểm tra xem một chuỗi có ở dạng UTF-8 không

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
1

Đầu ra trong HTML

Vì việc hiển thị một số mã HTML cho một trang web từ PHP là điều quá phổ biến, đây là cách chúng tôi có thể đảm bảo rằng chúng tôi đã đặt mã hóa phù hợp cho trình duyệt. Chúng tôi có thể làm điều đó chỉ bằng cách gửi tiêu đề trước đầu ra

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
2

Lưu ý về cơ sở dữ liệu

Cơ sở dữ liệu là một phần quan trọng trong việc xử lý mã hóa chính xác vì chúng được định cấu hình để sử dụng một cho tất cả dữ liệu chúng tôi có ở đó

Trong nhiều trường hợp, chúng là nơi chúng tôi sẽ lưu trữ tất cả các chuỗi của mình và từ đó chúng tôi sẽ đọc chúng để hiển thị chúng cho người dùng

Tôi khuyên bạn nên đảm bảo rằng mã hóa bạn đang sử dụng cho dự án của mình cũng giống như mã hóa bạn đã đặt trong cơ sở dữ liệu của mình để ngăn ngừa sự cố trong tương lai

Việc đặt mã hóa cho cơ sở dữ liệu của bạn phụ thuộc vào hệ thống cơ sở dữ liệu mà bạn sử dụng nên chúng tôi không thể mô tả mọi cách trong bài viết này. Tuy nhiên, thật hợp lý khi truy cập tài liệu trực tuyến và xem cách chúng tôi có thể thay đổi nó. Ví dụ: đây là cách thực hiện với PostgreSQL và với MySQL

Các lỗi liên quan đến mã hóa phổ biến trong PHP

Các ký tự UTF-8 không đúng định dạng, có thể được mã hóa không chính xác

Khi chuyển đổi một mảng thành JSON bằng

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
9, bạn có thể gặp sự cố này. Điều này chỉ có nghĩa là những gì PHP mong muốn nhận được dưới dạng UTF-8 không có trong mã hóa đó, vì vậy chúng tôi có thể giải quyết vấn đề bằng cách chuyển đổi nó trước

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
3

Lỗi mã hóa trong cơ sở dữ liệu

Khi đọc hoặc ghi vào cơ sở dữ liệu, bạn có thể gặp một số ký tự lạ, chẳng hạn như sau

SOS SOS CQD CQD Titanic. We are sinking fast. Passengers are being put into boats. Titanic
4

Lỗi này thường là dấu hiệu cho thấy mã hóa bạn đang sử dụng để đọc chuỗi không giống với mã mà cơ sở dữ liệu đang sử dụng. Để khắc phục sự cố này, hãy đảm bảo rằng bạn đang kiểm tra mã hóa của chuỗi trước khi lưu trữ và bạn đã đặt đúng mã hóa trong cơ sở dữ liệu của mình

Phần kết luận

Mã hóa đôi khi khó hiểu, nhưng hy vọng với bài viết này, nó sẽ rõ ràng hơn một chút và bạn cảm thấy sẵn sàng hơn để sửa bất kỳ lỗi nào có thể xảy ra theo cách của mình

Bài học quan trọng nhất cần rút ra là luôn nhớ rằng tất cả các chuỗi đều có mã hóa liên quan, vì vậy hãy đảm bảo rằng bạn đang sử dụng đúng mã ngay từ lần đầu tiên bạn gặp nó và sử dụng cùng một mã hóa trong toàn bộ dự án của bạn, bao gồm cả cơ sở dữ liệu . Nếu bạn cần chọn một cái, hãy chọn một cái hiện đại và phổ biến, chẳng hạn như UTF-8, vì nó sẽ phục vụ tốt cho bạn với bất kỳ ký tự mới nào có thể xuất hiện trong tương lai và nó được thiết kế rất tốt

Cách đặt mã hóa thành 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. )

Làm cách nào để đặt bộ ký tự trong MySQL PHP?

Cách đặt bộ ký tự UTF

Để thay đổi mã hóa bộ ký tự thành UTF-8 cho chính cơ sở dữ liệu, hãy nhập lệnh sau tại dấu nhắc mysql>. Thay dbname bằng tên cơ sở dữ liệu. Sao chép ALTER DATABASE dbname CHARACTER SET utf8 COLLATE utf8_General_ci ; .

Bộ ký tự trong PHP là gì?

Có cài đặt mã hóa ký tự bên trong php của bạn. tập tin ini. Theo mặc định, mã này được đặt thành mã hóa Latinh tiêu chuẩn (ISO-8859) . Nếu bạn muốn mã hóa trang của mình bằng các ký tự khác, chẳng hạn như tiếng Ả Rập hoặc tiếng Hindi, bạn sẽ cần thay đổi điều này.