2012-10-23 47 views
6

Đây có thể là một cái gì đó đơn giản. Tôi thề tôi đã tìm kiếm trực tuyến câu trả lời và không tìm thấy nó. Vì trường hợp cụ thể của tôi là một chút không điển hình, tôi cuối cùng đã quyết định hỏi ở đây.Thao tác dữ liệu utf8mb4 từ MySQL với PHP

Tôi có một vài bảng trong MySQL mà tôi đang sử dụng cho một chương trình tiếng Trung Quốc. Nó cần để có thể hỗ trợ tất cả các ký tự Trung Quốc có thể, bao gồm cả những người hiếm hoi mà không có hỗ trợ phông chữ tuyệt vời. Một ô mẫu trong bảng có thể là thế này:

東 菄 鶇 䍶 倲 涷 蝀 凍 鯟 崠 埬 䰤

Để nhận được rằng để làm việc ngay trong cơ sở dữ liệu, tôi đã để đặt mã hóa/đối chiếu thành utf8mb4. Càng xa càng tốt. Thật không may khi tôi kéo cùng một chuỗi vào PHP, nó được in như thế này:??

東 菄 鶇 䍶 倲 ?? 涷 蝀 凍 鯟 崠 埬 䰤

Làm thế nào tôi có thể cuối cùng đã giết tắt các dấu chấm hỏi còn lại và khiến chúng hiển thị như là các hình tượng đơn cực mà chúng nên là? Tôi đã có trang php sử dụng mã hóa UTF8 trong thẻ và dưới dạng thẻ meta.

Tại sao họ không thể liên lạc với nhau? Tôi đang làm gì sai?

+0

Bạn có đang đặt mã hóa kết nối cơ sở dữ liệu không? Nếu vậy, làm thế nào và để những gì? Các ký tự thực sự được chuyển đổi ở đâu đó hay chỉ là vấn đề hiển thị? 'Bin2hex()' trên chuỗi đó cung cấp cho bạn trong PHP là gì? – deceze

Trả lời

15

Tôi chỉ đơn giản đoán rằng bạn đang đặt bảng thành utf8mb4, nhưng mã hóa kết nối của bạn được đặt thành utf8. Bạn cũng phải đặt nó thành utf8mb4, nếu không MySQL sẽ chuyển đổi dữ liệu được lưu trữ utf8mb4 thành utf8, sau đó không thể mã hóa các ký tự Unicode "cao". (Vâng, đó là một phong cách riêng MySQL.)

Trên một kết nối MySQL liệu, nó sẽ phải trông như thế này:

SET NAMES 'utf8mb4'; 
SELECT * FROM `my_table`; 

Bạn sẽ phải thích ứng đó để cách tốt nhất của khách hàng, tùy thuộc về cách bạn kết nối với MySQL từ PHP (mysql, mysqli hoặc PDO).


Để thực sự làm rõ (có, sử dụng phần mở rộng mysql_ vì đơn giản, không làm điều đó ở nhà):

mysql_connect(...); 
mysql_select_db(...); 
mysql_set_charset('utf8mb4');  // adapt to your mysql connector of choice 

$r = mysql_query('SELECT * FROM `my_table`'); 

var_dump(mysql_fetch_assoc($r)); // data will be UTF8 encoded 
+0

Tôi đang truy cập từ PHP và hiện đang sử dụng 'mb_internal_encoding ('UTF-8'); 'Điều đó có ảnh hưởng đến giải pháp không? Có một thứ như 'mb_internal_encoding ('UTF-8MB4');'? – Yhilan

+0

Không, 'mb_internal_encoding' chỉ đặt mã hóa nội bộ cho các hàm' mb_', nó không liên quan gì tới MySQL. Bạn sẽ nhận được UTF-8 bình thường từ MySQL, 'utf8mb4' chỉ là một thứ nội bộ cho MySQL. – deceze

+0

Vậy làm thế nào tôi có thể sử dụng SET NAMES từ bên trong PHP? Hoặc tôi đang đi về điều này sai và bằng cách nào đó nên đặt nó từ bên trong một cái gì đó như phpmyadmin? – Yhilan

2

Chỉ cần để thêm vào câu trả lời @ deceze, tôi khuyên bạn nên được cấu hình tốt Máy chủ MySQL (cho tôi, trong /etc/mysql/mysql.conf.d/mysqld.cnf). Dưới đây là các tùy chọn cấu hình để đảm bảo bạn đang sử dụng utfmb4, mặc dù tôi khuyên bạn nên thực hiện mọi tùy chọn cấu hình MySQL, mặc dù khó khăn vì nó có nhiều mặc định rất không tối ưu.

[client] 

default-character-set   = utf8mb4 

[mysql] 

default_character_set   = utf8mb4 

[mysqld] 

init-connect     = "SET NAMES utf8mb4" 
character-set-client-handshake = FALSE 
character-set-server   = "utf8mb4" 
collation-server    = "utf8mb4_unicode_ci" 
autocommit      = 1 
block_encryption_mode   = "aes-256-cbc" 

Điều cuối cùng chỉ là giá trị mặc định. Ngoài ra, init-connect không phải thực hiện mọi lúc. Giữ mã sạch sẽ.Bây giờ chạy:

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'; 

Bạn nên quay trở lại giống như sau:

+--------------------------+--------------------+ 
| Variable_name   | Value    | 
+--------------------------+--------------------+ 
| character_set_client  | utf8mb4   | 
| character_set_connection | utf8mb4   | 
| character_set_database | utf8mb4   | 
| character_set_filesystem | binary    | 
| character_set_results | utf8mb4   | 
| character_set_server  | utf8mb4   | 
| character_set_system  | utf8    | 
| collation_connection  | utf8mb4_unicode_ci | 
| collation_database  | utf8mb4_unicode_ci | 
| collation_server   | utf8mb4_unicode_ci | 
+--------------------------+--------------------+ 

Và có vẻ như bạn đang làm điều này đã có, nhưng không làm tổn thương để xác định một cách rõ ràng về tạo bảng:

CREATE TABLE `mysql_table` (
    `mysql_column` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`mysql_column`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

Hy vọng điều này sẽ giúp ai đó.

+0

đừng quên khởi động lại mysql với 'service mysqld start' hoặc bằng' /etc/init.d/mysqld restart' sau khi thay đổi tệp cấu hình – salvob

+1

Tại sao có các cài đặt có cùng tên nhưng với dấu gạch nối hoặc dấu gạch dưới và dấu ngoặc kép hoặc không có báo giá? –

+0

Vì tôi chậm phát triển? Đã chỉnh sửa (cảm ơn!) – Eugene

Các vấn đề liên quan