แก้ปัญหาภาษาไทยเพี้ยนใน MySQL ด้วย UTF8MB4

ข้อความภาษาไทยในฐานข้อมูลเพี้ยนเป็น ??? แก้ได้ด้วยการตั้งค่า Character Set ให้ถูกต้อง

แก้ปัญหาภาษาไทยเพี้ยนใน MySQL ด้วย UTF8MB4 MySQL

ทำไมข้อความภาษาไทยจึงเพี้ยนเป็นเครื่องหมายแปลกๆ?

ข้อความภาษาไทยเพี้ยนเป็น "?", "???", "□□□" หรือตัวอักษรแปลก ๆ อื่น ๆ เกิดจาก "Character Set" ที่ฐานข้อมูล (Database) ใช้ไม่ถูกต้อง Character Set คือการสอบเทียม (Encoding) ที่บอกว่า "ตัวอักษรนี้ ควรแสดงผลอย่างไร"

ตัวอย่างปัญหา:

Character Set ทั่วไปใน MySQL

Character Set ที่ใช้บ่อย:

การโต้ตอบ (Collation) เป็นส่วนอีกอย่างหนึ่ง Collation บอกว่า "ตัวอักษรไหนควร Sorted ไว้ก่อนหลัง" เช่น utf8mb4_unicode_ci หมายถึง UTF8MB4 Character Set กับ Unicode Collation ที่ Case-Insensitive (ไม่แยกแยะตัวพิมพ์ใหญ่เล็ก)

วิธีแก้: เปลี่ยนจาก Latin1 เป็น UTF8MB4

วิธีแก้ใน phpMyAdmin (ที่ง่ายที่สุด):

  1. Login phpMyAdmin ผ่าน cPanel
  2. เลือก Database ที่ต้องการแก้
  3. ไปยัง Tab Operations
  4. หา Collation และเปลี่ยนเป็น utf8mb4_unicode_ci หรือ utf8mb4_general_ci
  5. คลิก Go หรือ Apply

ขั้นตอนหลังจากนั้น เปลี่ยน Character Set ของแต่ละ Table:

  1. ในแถบด้านซ้าย เลือก Table (เช่น wp_posts)
  2. ไปยัง Tab Operations
  3. หา Collation และเปลี่ยนเป็น utf8mb4_unicode_ci
  4. คลิก Go
  5. ทำซ้ำสำหรับทุก Table ใน Database

ดำเนินการเปลี่ยน Character Set ของแต่ละ Column

นอกจากการเปลี่ยน Database และ Table แล้ว ควรเปลี่ยน Column เดี่ยว ๆ (Text Field) ให้เป็น UTF8MB4 ด้วย

ใน phpMyAdmin GUI

  1. เลือก Table ที่ต้องการแก้
  2. ไปยัง Tab Structure
  3. ดู Column ที่เป็น VARCHAR, TEXT, LONGTEXT เป็นต้น (Text Field)
  4. คลิก "Change" ไอคอนสำหรับ Column นั้น
  5. ค้นหา Collation แล้วเปลี่ยนเป็น utf8mb4_unicode_ci
  6. คลิก Go หรือ Save
  7. ทำซ้ำสำหรับทุก Text Column

ใช้ SQL Command (สำหรับผู้ช่วย)

-- 1. เปลี่ยน Character Set ของ Database ทั้งหมด
ALTER DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 2. เปลี่ยน Character Set ของ Table
ALTER TABLE table_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 3. เปลี่ยน Character Set ของ Column เดี่ยว
ALTER TABLE table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 4. เปลี่ยนทั้ง Table โดย Loop ผ่าน phpMyAdmin
-- หากต้องเปลี่ยนทีเดียวหลาย Table ใช้ SQL นี้ (ต้องใช้ root user):
SELECT CONCAT('ALTER TABLE ',TABLE_NAME,' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='database_name';
-- จากนั้น Copy ผลลัพธ์แล้วรัน SQL ต่อเนื่อง
Tip: เปลี่ยน Character Set บนเว็บที่กำลังใช้งาน เว็บอาจหยุดชั่วคราว (Lock Table เกิดขึ้น) แต่ไม่เสียหายข้อมูลหรือยูสเซอร์ สำหรับเว็บขนาดใหญ่ ลองทำการเปลี่ยนในช่วงเวลาที่ Traffic น้อยที่สุด (เช่น ตอนกลางคืน)

ตั้งค่า Connection Character Set ให้ Web Application

นอกจากตั้งค่า Database แล้ว ต้องบอก Application (WordPress, PHP, เป็นต้น) ให้ใช้ UTF-8 Character Set เมื่อติดต่อ MySQL

สำหรับ WordPress ใน wp-config.php

// ตรวจหาบรรทัดนี้ใน wp-config.php แล้วทำให้เป็นแบบนี้:
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', 'utf8mb4_unicode_ci');

// ถ้าไม่มี ให้เพิ่มบรรทัดเหล่านี้ก่อน "That's all, stop editing!":
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', 'utf8mb4_unicode_ci');

สำหรับ PHP Custom Script

// สำหรับ MySQLi
$conn = new mysqli("localhost", "username", "password", "database");
$conn->set_charset("utf8mb4");

// สำหรับ PDO
$dsn = 'mysql:host=localhost;dbname=database;charset=utf8mb4';
$pdo = new PDO($dsn, 'username', 'password');

ใน .htaccess สำหรับ Apache

AddDefaultCharset utf-8
php_value default_charset utf-8

ตรวจสอบว่า Character Set ถูกเปลี่ยนเรียบร้อย

หลังจากเปลี่ยนแล้ว ตรวจสอบด้วยคำสั่ง SQL นี้:

-- 1. ตรวจสอบ Character Set ของ Database
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME='database_name';
-- ควรแสดง utf8mb4 และ utf8mb4_unicode_ci

-- 2. ตรวจสอบ Character Set ของ Table
SHOW CREATE TABLE table_name;
-- ตรวจหาบรรทัด "CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"

-- 3. ตรวจสอบ Character Set ของแต่ละ Column
SHOW FULL COLUMNS FROM table_name;
-- ตรวจสอบ Column "Collation" ควรเป็น utf8mb4_unicode_ci
Tip: หลังจากเปลี่ยน Character Set เสร็จ ทดสอบการแสดงภาษาไทย Emoji โดยการเพิ่มข้อมูลทดสอบ ถ้ายังเพี้ยน อาจต้องตรวจสอบ Connection String ใน wp-config.php หรือ PHP Code อีกครั้ง

แก้ปัญหาที่พบบ่อย

Error: "เปลี่ยน Character Set แล้ว ตัวอักษรเก่ายังเพี้ยน"

เกิดเมื่อข้อมูลเก่า (ที่เก็บไว้ด้วย Latin1) ถูก Convert ผิด Character Set ไม่สามารถ "แปล" กลับเป็นตัวอักษรปกติได้

วิธีแก้: ต้อง Restore จาก Backup ที่ยังดี หรือ Export ข้อมูลออกมาเป็น CSV แล้วลบข้อมูลเก่า ใส่ข้อมูลใหม่ด้วย UTF-8 ถูกต้อง (วิธีนี้ยุ่งยาก) หรือลองใช้ Tool MySQL Converter ที่บุคคลที่สาม เช่น iconv หรือ Mysqldump --default-character-set=utf8mb4 แต่ก่อนเริ่มต้อง Backup ให้ปลอดภัยก่อน

Error: "ข้อมูล Emoji หรือตัวอักษรพิเศษหายไปหลังเปลี่ยน Character Set"

เกิดเมื่อใช้ utf8 (3 bytes) เก่า ลองแบบมี emoji (4 bytes) Conversion อาจทำให้ emoji หายไป

วิธีแก้: ต้อง Restore ข้อมูล Emoji ใหม่ เพราะข้อมูล Emoji ที่เก็บใน utf8 เก่า ตัวอักษรแล้วจึง Recover ไม่ได้ อนาคตหลังนี้เก็บใช้ utf8mb4 ให้ถูกต้อง

Error: "หลังเปลี่ยน Character Set WordPress ยังแสดงตัวอักษรไทยเพี้ยน"

อาจเกิดจากเบราว์เซอร์ Cache หรือ WordPress Cache ยังเก็บข้อมูลเก่าไว้

วิธีแก้: ล้าง WordPress Cache (ผ่าน W3 Total Cache Plugin หรือ Clear Cache ด้วยมือ) ล้าง Browser Cache (Ctrl+Shift+Delete) จากนั้น Refresh หน้าเว็บใหม่

Error: "ไม่สามารถทำ ALTER TABLE ได้ เพราะเกิด MySQL Error"

อาจเกิดจากไม่มี Free Disk Space หรือ Table กำลังถูกใช้ หรือ Hosting จำกัดการใช้ ALTER TABLE

วิธีแก้: ลองกำหนดเวลา ALTER ในช่วง Maintenance (ที่ Traffic น้อยที่สุด) หรือติดต่อ Hosting Provider ขอให้ยกเลิก Limit ALTER TABLE ชั่วคราว

Error: "หลังทำ utf8mb4 Emoji แสดงผลเป็น □ หรือหายไปเลย"

อาจเกิดจากเว็บเบราว์เซอร์ไม่รองรับ Emoji Font หรือ CSS ไม่ได้กำหนด Font ที่รองรับ Emoji

วิธีแก้: ตรวจสอบ HTML Head ของเว็บว่ามีบรรทัด `` หรือไม่ และลองเพิ่ม Emoji Font ให้กับ CSS เช่น `font-family: 'Apple Color Emoji', 'Segoe UI Emoji', sans-serif;` ลองใช้เบราว์เซอร์อื่น เช่น Chrome หรือ Firefox เพื่อตรวจสอบว่า Emoji ถูกแสดงผลได้จริงหรือไม่


คำถามที่พบบ่อย

Q: utf8 กับ utf8mb4 มีความต่างกันตรงไหน?

A: utf8 ในภาษาทั่วไป (Unicode) รองรับ 4 Bytes แต่ MySQL utf8 เก่า (created ก่อน version 5.5.3) เก็บได้ 3 Bytes สูงสุด ดังนั้นไม่รองรับ Emoji หรืออักษร Rare ที่ต้อง 4 Bytes ในขณะที่ utf8mb4 ในทั้ง MySQL รองรับ 4 Bytes เต็มตัว ควรใช้ utf8mb4 เสมอ

Q: ต้องเปลี่ยน Character Set ทั้ง Database หรือแค่ Table ที่เก็บภาษาไทย?

A: ควรเปลี่ยนทั้ง Database และทุก Table เพื่อให้เกิด Consistency ถ้าสร้าง Table ใหม่ในภายหลัง มันจะ Inherit Character Set จาก Database โดยอัตโนมัติ

Q: เปลี่ยน Character Set แล้ว Storage ของ Database จะเพิ่มขึ้นหรือ?

A: ไม่มากนัก utf8mb4 ใช้ 4 Bytes ต่อตัวอักษร แต่ Database ส่วนใหญ่เก็บ ASCII (ตัวอักษรอังกฤษ) ที่ใช้ 1 Byte เท่านั้น ดังนั้นการเปลี่ยนเป็น utf8mb4 จะเพิ่ม Storage เพียง 5-10% ที่สูงสุด (ขึ้นอยู่กับปริมาณข้อความภาษาไทย)

อยากรู้ว่าการตั้งค่าโดเมนหรือ DNS ของคุณถูกต้องหรือไม่ ลองตรวจสอบฟรีได้ที่ dnsxray.com เครื่องมือวิเคราะห์สุขภาพโดเมนที่ใช้งานง่าย