Jak wygląda problem
Przed
INSERT INTO wp_posts (post_title) VALUES ('Zażółć gęślą jaźń – menu na wynos');Po
INSERT INTO wp_posts (post_title) VALUES ('Zażółć gęślą jaźń – menu na wynos');Skąd się to bierze
WordPress zapisuje tekst w UTF-8. Wiele starszych instalacji tworzyło jednak tabele jako latin1 albo łączyło się z bazą w latin1. Dopóki zapis i odczyt popełniają ten sam błąd, nikt tego nie zauważa. Po przeniesieniu na nowy serwer, eksporcie w phpMyAdmin albo zmianie kodowania połączenia każda polska litera nagle zamienia się w dwa znaki.
DB_CHARSETwwp-config.phptolatin1albo nie zgadza się z tabelami.- Zrzut wyeksportowano jako
latin1, a zaimportowano jakoutf8mb4– albo odwrotnie. - Wtyczka lub skrypt importujący przekonwertował już zepsuty tekst jeszcze raz. Powstaje wtedy podwójnie zakodowany tekst, np.
Ĺ‚.
Naprawa eksportu
- Zrób kopię zapasową bazy, zanim cokolwiek zmienisz.
- Wyeksportuj dotknięte tabele do pliku
.sql, np. w phpMyAdmin albo poleceniemmysqldump --default-character-set=utf8mb4. - Upuść plik w polu powyżej. Mojibuster naprawia tylko zepsute miejsca i pokazuje każdą zmianę.
- Pobierz naprawiony plik i zaimportuj go w
utf8mb4do świeżej bazy testowej. - Sprawdź stronę. Jeśli wszystko wygląda dobrze, zaimportuj dane do bazy produkcyjnej.
Zrzut nigdy nie jest wysyłany na serwer – a to ważne, bo zwykle zawiera konta użytkowników, adresy e-mail i komentarze. Więcej na ten temat dla firm i inspektorów ochrony danych.
Uwaga na dane serializowane
WordPress przechowuje część ustawień w wp_options i wp_postmeta jako serializowane wartości PHP, np. s:9:"KrakĂłw";. Liczba oznacza długość w bajtach. Po naprawie na s:7:"Kraków"; długość 9 już się nie zgadza, a WordPress odrzuca taką wartość. Dlatego najpierw naprawiaj tabele z treścią, takie jak wp_posts, wp_comments i wp_terms. Dla opcji lepszym narzędziem jest wp search-replace z WP-CLI, które aktualizuje długości.
Usuń przyczynę w MySQL
- Przełącz tabele i połączenie na
utf8mb4i ustawdefine('DB_CHARSET', 'utf8mb4');wwp-config.php. - Jeśli kolumna
latin1zawiera bajty UTF-8, nie konwertuj jej bezpośrednio – zakodowałbyś ją po raz drugi. Zwykła droga prowadzi przez typ binarny: najpierwMODIFY … LONGBLOB, potemMODIFY … LONGTEXT CHARACTER SET utf8mb4. - Każdą zmianę najpierw przetestuj na kopii bazy.
Najczęstsze pytania
Czy mogę naprawić całą bazę WordPressa naraz?
Tak, także duże zrzuty SQL. Uważaj jednak na dane serializowane w wp_options i wp_postmeta – WP-CLI radzi sobie z nimi lepiej.
Czy poprawne znaki w zrzucie zostaną zmienione?
Nie. Mojibuster naprawia tylko ciągi, które wyraźnie są zepsute. Poprawny tekst zostaje bez zmian.
Czym różni się utf8 od utf8mb4?
W MySQL utf8 zapisuje tylko znaki do trzech bajtów, więc emoji giną. utf8mb4 to prawdziwy UTF-8 i właściwy wybór dla WordPressa.
Czy to działa także w innych systemach niż WordPress?
Tak. Joomla, Drupal, Magento czy własna aplikacja na MySQL lub MariaDB mają ten sam problem i to samo rozwiązanie.