Vấn đề của bạn là SET NAMES 'utf8_persian_ci'
của bạn lệnh không hợp lệ (utf8_persion_ci là một đối chiếu , không phải là mã hóa ). Nếu bạn chạy nó trong một thiết bị đầu cuối, bạn sẽ thấy lỗi Unknown character set: 'utf8_persian_ci'
. Do đó, ứng dụng của bạn, khi nó được lưu trữ dữ liệu, đang sử dụng latin1
bộ ký tự. MySQL đã diễn giải đầu vào của bạn dưới dạng các ký tự latin1 mà sau đó nó được lưu trữ được mã hóa dưới dạng utf-8. Tương tự như vậy khi dữ liệu được lấy lại, MySQL đã chuyển đổi nó từ UTF-8 trở lại latin1 và (hy vọng là hầu hết thời gian) các byte ban đầu mà bạn đã cung cấp cho nó.
Nói cách khác, tất cả dữ liệu của bạn trong cơ sở dữ liệu hoàn toàn bị xáo trộn, nhưng nó vẫn hoạt động bình thường.
Để khắc phục điều này, bạn cần hoàn tác những gì bạn đã làm. Cách đơn giản nhất là sử dụng PHP:
-
SET NAMES latin1;
- Chọn mọi trường văn bản từ mọi bảng.
-
SET NAMES utf8;
- Cập nhật các hàng giống nhau bằng cách sử dụng cùng một chuỗi không thay đổi.
Ngoài ra, bạn có thể thực hiện các bước này bên trong MySQL, nhưng rất khó vì MySQL hiểu dữ liệu nằm trong một bộ ký tự nhất định. Bạn cần sửa đổi các cột văn bản của mình thành loại BLOB, sau đó sửa đổi chúng trở lại sang các loại văn bản có bộ ký tự utf8. Xem phần ở cuối ALTER TABLE
Tài liệu MySQL có nhãn "Cảnh báo" màu đỏ
.
Sau khi bạn thực hiện một trong những điều này, các byte được lưu trữ trong các cột cơ sở dữ liệu của bạn sẽ là bộ ký tự thực mà chúng yêu cầu. Sau đó, hãy đảm bảo rằng bạn luôn sử dụng mysql_set_charset('utf8')
trên bất kỳ quyền truy cập cơ sở dữ liệu nào từ PHP mà bạn có thể thực hiện trong tương lai! Nếu không bạn sẽ làm mọi thứ rối tung lên một lần nữa. (Lưu ý, không sử dụng mysql_query('SET NAMES utf8')
! Có những trường hợp ở góc (chẳng hạn như kết nối đặt lại) nơi có thể đặt lại điều này thành latin1
mà bạn không biết. mysql_set_charset()
sẽ đặt bộ ký tự bất cứ khi nào cần thiết.)
Tốt nhất là bạn nên chuyển khỏi mysql_*
các chức năng và PDO
được sử dụng thay vào đó bằng charset=utf8
trong PDO dsn
của bạn .