Cho em hỏi về MySQL, PDO
e đang làm project để cuối tháng bảo vệ, em làm trên localhost thì tạo data charset là utf8_unicode_ci rồi, rồi code php để insert dữ liệu vào thì nó không lưu tiếng việt ví dụ sản phẩm tên “Áo khoác” thì nó lưu là "Ão khoác " , nhưng khi select ra vẫn là có dấu tiếng việt đúng.
nay em up lên vps chạy nginx thử thì nó ko ra tiếng việt như trên local mà ra "Ão khoác " ( giống trong data ).
như vậy là sao ạ, ai chỉ em cách fix đc ko ạ.
em kết nối PDO và mọi table đều là utf8_unicode_ci
Thử dùng utf8_general_ci.
####1. Để select, insert dữ liệu tiếng Việt vào database bằng PDO bạn cần đặt charset khi khởi tạo PDO:
####2. Để hiển thị tiếng Việt trên web, bạn cần set thẻ meta cho html:
Charset của table là
utf8_unicode_ci
thì đúng rồi. Bạn xem có làm sai chỗ nào không? Nếu không được thì đưa code của bạn lên cho mọi người xem cho.Bạn có thể xem thêm cách dùng PDO chi tiết tại đây ==> https://viblo.asia/pht/posts/Do754EvLKM6
giờ thay charset của data thành general hả a
không được anh ạ, vẫn select ra kí tự y như trong data chứ k encode sang có dấu đc
Dữ liệu đó bị lỗi rồi, bạn thử insert dữ liệu mới xem thế nào. Show code phần insert lên đây mình xem cho.
$ten_dm = $_POST[‘ten_dm’];
$trang_thai = 0;
if(isset($_POST[‘trang_thai’]))
{
$trang_thai = 1;
}
$query = “INSERT INTO danh_muc(ten_dm, trang_thai) VALUES(’$ten_dm’,$trang_thai)”;
$count = $db->exec($query);
if($count > 0)
{
header(‘location: ds_dm.html’);
}
à , trên localhost mình thêm charset=utf8 vào kết nối thì klhi thêm tiếng việt nó vẫn lưuw tiếng việt và khi select cũng được.
nhưng mình không hiểu tại sao khi không có charset=utf8 trong kết nối, trên local thì lưu dạng ko phải utf8 nhưng khi select ra vẫn là utf8 mà khi up lên hosting thì select ra không ra utf8.
thế là giờ mk phải insert lại từ đầu
Môi trường khác biệt bạn ạ, có thể ở localhost bạn để database mặc định character set là utf8 hoặc config của MySQL được set mặc định charset là utf8 nhưng trên hosting thì không.
$ten_dm = $POST[‘tendm’];
$trang_thai = 0;
if(isset($POST[‘trangthai’])) {
$trang_thai = 1;
}
$query = “INSERT INTO danh_muc(ten_dm, trang_thai) VALUES(’$ten_dm’,$trang_thai)”;
$count = $db->exec($query);
if($count > 0) {
header(‘location: ds_dm.html’);
}
Việc hiển thị không đúng tiếng Việt có thể do 1 vài yếu tố. Trước mắt chúng ta làm rõ các encoding:
1- Encoding phía mysql server. Với các phiên bản mới như MySQL 5.6, 5.7 thì charset mặc định là utf8, tuy nhiên với các phiên bản cũ thì có thể được set sang Swedish (ISO-8859-1)
2- Khi gửi câu query thì encoding gì?
3- Khi nhận result về thì encoding gì?
3- Khi lấy được result, hiển thị lên web thi
dung
encoding gì?Trở về trường hợp của bạn,
1- Phía local, mình đoán 1 trong các encoding của bạn không phải utf8 (có thể bạn quên gọi truyền charset vào DSN, hoặc server encoding kiểu khác), thế nên khi ghi vào CSDL và view trên Navicat/hoặc view bằng mysql_client mặc định (view trên PHPMyAdmin lại khác nhé) thì bị sai encoding nên hiển thị sai mặc dù codepage ghi vào đúng. Bạn cứ tưởng tượng, bạn ghi ký tự A là codepage 100, nhưng sang encoding mới nó là lại Á. Thế nhưng khi lấy về, nó vẫn lấy đúng codepage và nếu set ở HTML charset=“utf8” thì hiển thị vẫn đúng.
Còn lần sau bạn thử với DSN có utf8, do encoding của bảng không đúng nên nó hiển thị lỗi, nhưng trả về lại là encoding utf8 nên bạn thấy đúng. Lúc này, kể cả html bạn không cần để charset=“utf8” vẫn ok.
2- Còn phía hosting, thì trường đó có thể để utf8, nhưng do bạn đẩy query lên lại không phải utf8 nên khi lưu vào db vẫn không đúng (ví dụ chữ  của ISO-8859-1, nhưng sang utf8 lại là ô. Thế nên Áo khoác bên ISO-8859-1 sang utf8 lại là Ão khoác) Khi bạn lấy về, tất nhiên codepage vẫn thế, nhưng lại tùy result set encode gì, rồi hiển thị trên HTML charset gì mà nó hiển thị không đúng (ví dụ, result vẫn là utf8 và charset html vẫn là utf8 thì hiển nhiên nó hiển thị Ão khoác rồi. Nhưng nếu bạn set charset của html là “ISO-8859-1” thì lại hiển thị đúng ^^)
Theo mình, nếu tốt nhất nên đồng bộ UTF8 ở cả 3 nơi:
1- Các table và text encoding bằng utf8 (general hay unicode cũng được, nó chỉ khác nhau về sắp xếp). Sau mình test query, làm procedure … cũng dễ dàng hơn (thậm chí sửa db bằng tay)
2- Add utf8 vào server và client command (vào DSN hoặc gọi SET NAMES utf8).
Việc gọi SET NAMES utf8 sẽ tương đương với (ngoài ra có thể gọi thêm collation để làm sort)
SET character_set_client = x; //query gọi lên được hiểu là encoding utf8
SET character_set_results = x; //result trả về cũng là encoding utf8
SET character_set_connection = x; // char của kết nối cũng là utf8
(hoặc SET CHARACTER SET utf8. Cái này thì nó khác ở chỗ SET collation_connection = @@collation_database;)
3-Mặc định browser cũng sẽ tự detect encoding, tuy nhiên nhiều browser cơ chế detect cũng không tốt. Do đó mình cứ set 1 cái directive charset=“utf8” cho yên tâm luôn.