อาการเป็นอย่างไร
ก่อนแก้
INSERT INTO wp_posts (post_title) VALUES ('เมนูà¸à¸²à¸«à¸²à¸£à¹„ทย ชาเขียวเย็น');หลังแก้
INSERT INTO wp_posts (post_title) VALUES ('เมนูอาหารไทย ชาเขียวเย็น');มาจากไหน
WordPress เก็บข้อความเป็น UTF-8 แต่เว็บเก่าหลายแห่งสร้างตารางเป็น latin1 หรือเชื่อมต่อด้วย latin1 (หรือ tis620) ตราบใดที่เขียนและอ่านผิดแบบเดียวกัน ก็ไม่มีใครสังเกต พอย้ายไปเซิร์ฟเวอร์ใหม่ ส่งออกด้วย phpMyAdmin หรือเปลี่ยน charset ของการเชื่อมต่อ ตัวอักษรไทยทุกตัวก็กลายเป็นอักขระแปลกๆ ทันที
DB_CHARSETในwp-config.phpเป็นlatin1หรือไม่ตรงกับตาราง- ส่งออกไฟล์ dump เป็น
latin1แล้วนำเข้าเป็นutf8mb4หรือกลับกัน - ปลั๊กอินหรือสคริปต์นำเข้าแปลงข้อความที่เพี้ยนอยู่แล้วซ้ำอีกรอบ จนเกิด ข้อความซ้อนสองชั้น เช่น
à ¸Â
แก้ไฟล์ส่งออก
- สำรองฐานข้อมูลก่อนแก้อะไรทั้งนั้น
- ส่งออกตารางที่มีปัญหาเป็นไฟล์
.sqlเช่นผ่าน phpMyAdmin หรือmysqldump --default-character-set=utf8mb4 - ลากไฟล์ใส่กล่องด้านบน Mojibuster แก้เฉพาะจุดที่เสียและแสดงทุกการเปลี่ยนแปลง
- ดาวน์โหลดไฟล์ที่แก้แล้ว แล้วนำเข้าด้วย
utf8mb4ลงฐานข้อมูลทดสอบใหม่ - ตรวจเว็บไซต์ ถ้าทุกอย่างถูกต้อง จึงนำเข้าฐานข้อมูลจริง
ไฟล์ dump จะไม่ถูกอัปโหลดเลย ซึ่งสำคัญ เพราะมักมีบัญชีผู้ใช้ อีเมล และความคิดเห็น อ่านเพิ่มได้ที่ ข้อมูลผู้ให้บริการ
ระวังข้อมูลแบบ serialized
WordPress เก็บการตั้งค่าบางอย่างใน wp_options และ wp_postmeta เป็นค่า PHP แบบ serialized เช่น s:18:"สวัสดี"; ตัวเลขคือความยาวเป็นไบต์ (ตัวอักษรไทยตัวละ 3 ไบต์) เมื่อข้อความเปลี่ยนความยาว ตัวเลขจะไม่ตรงอีก และ WordPress จะทิ้งค่านั้น ดังนั้นให้แก้ตารางเนื้อหาอย่าง wp_posts, wp_comments และ wp_terms ก่อน ส่วนตาราง options ใช้ wp search-replace ของ WP-CLI จะดีกว่า เพราะปรับความยาวให้
แก้ที่ต้นเหตุใน MySQL
- เปลี่ยนตารางและการเชื่อมต่อเป็น
utf8mb4และตั้งdefine('DB_CHARSET', 'utf8mb4');ในwp-config.php - ถ้าคอลัมน์
latin1เก็บไบต์ UTF-8 อยู่ อย่าแปลงตรงๆ เพราะจะเข้ารหัสซ้ำอีกรอบ วิธีปกติคือผ่านชนิด binary ก่อน:MODIFY … LONGBLOBแล้วจึงMODIFY … LONGTEXT CHARACTER SET utf8mb4 - ทดสอบทุกการเปลี่ยนแปลงกับสำเนาฐานข้อมูลก่อนเสมอ
คำถามที่พบบ่อย
แก้ทั้งฐานข้อมูล WordPress ในครั้งเดียวได้ไหม
ได้ แม้เป็นไฟล์ SQL ขนาดใหญ่ แต่ระวังข้อมูล serialized ใน wp_options และ wp_postmeta ใช้ WP-CLI จะดีกว่า
ตัวอักษรที่ถูกอยู่แล้วในไฟล์จะถูกเปลี่ยนไหม
ไม่ Mojibuster แก้เฉพาะลำดับอักขระที่เสียชัดเจน ข้อความที่ถูกต้องคงเดิม
utf8 กับ utf8mb4 ต่างกันอย่างไร
ใน MySQL utf8 เก็บอักขระได้สูงสุดสามไบต์ อีโมจิจึงหายไป utf8mb4 คือ UTF-8 จริงและเป็นตัวเลือกที่ถูกสำหรับ WordPress
ใช้กับระบบอื่นนอกจาก WordPress ได้ไหม
ได้ Joomla, Drupal, Magento หรือแอปของคุณเองบน MySQL หรือ MariaDB มีปัญหาเดียวกันและแก้แบบเดียวกัน