Ako problém vyzerá
Pred
INSERT INTO wp_posts (post_title) VALUES ('KĹ•deÄľ šťastnĂ˝ch ÄŹatÄľov – ponuka na vĂkend');Po
INSERT INTO wp_posts (post_title) VALUES ('Kŕdeľ šťastných ďatľov – ponuka na víkend');Odkiaľ sa to berie
WordPress ukladá text v UTF-8. Mnoho starších inštalácií však vytvorilo tabuľky ako latin1 alebo sa k databáze pripájalo v latin1. Kým zápis aj čítanie robia rovnakú chybu, nikto si ničoho nevšimne. Po presune na nový server, exporte cez phpMyAdmin alebo zmene kódovania spojenia sa každé slovenské písmeno zrazu zmení na dva znaky.
DB_CHARSETvwp-config.phpjelatin1alebo nesúhlasí s tabuľkami.- Dump bol exportovaný ako
latin1a importovaný akoutf8mb4– alebo naopak. - Plugin alebo importný skript previedol už poškodený text ešte raz. Vzniká tak dvojito zakódovaný text ako
Äľ.
Oprava exportu
- Pred akoukoľvek zmenou zálohujte databázu.
- Exportujte postihnuté tabuľky do súboru
.sql, napríklad v phpMyAdmin alebo príkazommysqldump --default-character-set=utf8mb4. - Presuňte súbor do poľa vyššie. Mojibuster opraví len poškodené miesta a ukáže každú zmenu.
- Stiahnite opravený súbor a naimportujte ho ako
utf8mb4do novej testovacej databázy. - Skontrolujte web. Ak všetko vyzerá správne, naimportujte dáta do ostrej databázy.
Dump sa nikdy nenahráva na server – a to je dôležité, pretože zvyčajne obsahuje používateľské účty, e-mailové adresy a komentáre. Viac pre firmy a zodpovedné osoby.
Pozor na serializované dáta
WordPress ukladá časť nastavení v wp_options a wp_postmeta ako serializované hodnoty PHP, napríklad s:6:"ÄŚaj";. Číslo udáva dĺžku v bajtoch. Po oprave na s:4:"Čaj"; už dĺžka 6 nesúhlasí a WordPress takúto hodnotu zahodí. Preto najprv opravujte tabuľky s obsahom, ako wp_posts, wp_comments a wp_terms. Pre voľby je lepším nástrojom wp search-replace z WP-CLI, ktorý dĺžky aktualizuje.
Odstránenie príčiny v MySQL
- Prepnite tabuľky aj spojenie na
utf8mb4a nastavtedefine('DB_CHARSET', 'utf8mb4');vwp-config.php. - Ak stĺpec
latin1obsahuje bajty UTF-8, neprevádzajte ho priamo – zakódovali by ste ho druhýkrát. Obvyklá cesta vedie cez binárny typ: najprvMODIFY … LONGBLOB, potomMODIFY … LONGTEXT CHARACTER SET utf8mb4. - Každú zmenu najprv vyskúšajte na kópii databázy.
Časté otázky
Môžem opraviť celú databázu WordPressu naraz?
Áno, aj veľké SQL dumpy. Pozor však na serializované dáta v wp_options a wp_postmeta – WP-CLI si s nimi poradí lepšie.
Zmenia sa správne znaky v dumpe?
Nie. Mojibuster opravuje len reťazce, ktoré sú jasne poškodené. Správny text zostáva, aký je.
Aký je rozdiel medzi utf8 a utf8mb4?
V MySQL ukladá utf8 len znaky do troch bajtov, takže emoji sa strácajú. utf8mb4 je skutočné UTF-8 a pre WordPress správna voľba.
Funguje to aj pre iné systémy než WordPress?
Áno. Joomla, Drupal, Magento alebo vlastná aplikácia nad MySQL či MariaDB majú rovnaký problém a rovnaké riešenie.