مشکل چه شکلی دارد
قبل
INSERT INTO wp_posts (post_title) VALUES ('ط³ظ„ط§ظ… ط¯ظˆط³طھ ظ…ظ†طŒ ط³ظپط§ط±ط´ ط§ط±ط³ط§ظ„ ط´ط¯');بعد
INSERT INTO wp_posts (post_title) VALUES ('سلام دوست من، سفارش ارسال شد');از کجا میآید
وردپرس متن را با UTF-8 ذخیره میکند. اما بسیاری از نصبهای قدیمی جدولهایشان را با latin1 ساختهاند یا با latin1 به پایگاه داده وصل شدهاند. تا وقتی نوشتن و خواندن یک اشتباه را تکرار کنند، کسی چیزی نمیفهمد. پس از انتقال به سرور جدید، خروجی گرفتن با phpMyAdmin یا عوض کردن کدگذاری اتصال، هر حرف فارسی ناگهان دو نویسه میشود.
DB_CHARSETدرwp-config.phpبرابرlatin1است یا با جدولها نمیخواند.- خروجی با
latin1گرفته و باutf8mb4وارد شده است، یا برعکس. - افزونه یا اسکریپت درونریزی متن از قبل خراب را یک بار دیگر تبدیل کرده است. اینطور کدگذاری دوباره پیش میآید.
رفع فایل خروجی
- پیش از هر تغییری از پایگاه داده پشتیبان بگیرید.
- جدولهای آسیبدیده را در فایل
.sqlخروجی بگیرید، مثلاً با phpMyAdmin یاmysqldump --default-character-set=utf8mb4. - فایل را در کادر بالا رها کنید. Mojibuster فقط جاهای خراب را درست میکند و هر تغییر را نشان میدهد.
- فایل اصلاحشده را دانلود کنید و با
utf8mb4در یک پایگاه داده آزمایشی تازه وارد کنید. - سایت را بررسی کنید. اگر همهچیز درست بود، آن را در پایگاه داده اصلی وارد کنید.
فایل هیچجا آپلود نمیشود. این مهم است، چون معمولاً حسابهای کاربری، نشانیهای ایمیل و دیدگاهها در آن هست.
مراقب دادههای سریالشده (serialized) باشید
وردپرس بخشی از تنظیمات را در wp_options و wp_postmeta بهصورت مقدارهای سریالشدهٔ PHP نگه میدارد، مثلاً s:8:"سلام";. عدد، طول رشته بر حسب بایت است: در UTF-8 هر حرف فارسی دو بایت است. متن خراب طولی متفاوت از متن اصلاحشده دارد، پس پس از اصلاح عدد نمیخواند و وردپرس مقدار را دور میاندازد. بنابراین اول جدولهای محتوا مثل wp_posts، wp_comments و wp_terms را درست کنید. برای تنظیمات wp search-replace از WP-CLI بهتر است، چون طولها را بهروز میکند.
رفع علت در MySQL
- جدولها و اتصال را به
utf8mb4ببرید و درwp-config.phpخطdefine('DB_CHARSET', 'utf8mb4');را بگذارید. - اگر ستون
latin1بایتهای UTF-8 دارد، آن را مستقیم تبدیل نکنید، وگرنه متن بار دوم کدگذاری میشود. راه معمول از نوع دودویی میگذرد: اولMODIFY … LONGBLOBو بعدMODIFY … LONGTEXT CHARACTER SET utf8mb4. - هر تغییر را اول روی یک کپی از پایگاه داده امتحان کنید.
پرسشهای متداول
میتوانم کل پایگاه داده وردپرس را یکجا درست کنم؟
بله، حتی فایلهای بزرگ SQL. فقط به دادههای سریالشده در wp_options و wp_postmeta توجه کنید، چون WP-CLI آنها را بهتر مدیریت میکند.
آیا نویسههای درست در فایل تغییر میکنند؟
نه. Mojibuster فقط دنبالههایی را درست میکند که بهروشنی خراباند. متن سالم همانطور میماند.
تفاوت utf8 و utf8mb4 چیست؟
در MySQL، utf8 فقط نویسههایی تا سه بایت ذخیره میکند، پس ایموجیها از بین میروند. utf8mb4 UTF-8 واقعی است و انتخاب درست برای وردپرس است.
برای سیستمهایی غیر از وردپرس هم کار میکند؟
بله. Joomla، Drupal، Magento یا برنامهٔ خودتان روی MySQL یا MariaDB همین مشکل و همین راهحل را دارند.