Polskie znaki, krzaczki i UTF-8 w pigułce
żółw zamiast żółw to klasyk, który potrafi zepsuć całą stronę. Winne jest prawie zawsze jedno: dwa miejsca w systemie dogadują się w innym kodowaniu.
Prawie każdy widział na stronie coś takiego: żółw zamiast żółw. Albo pytajniki w rombach. Albo puste kwadraciki. Wygląda to na awarię, a zwykle jest zwykłym nieporozumieniem między dwiema częściami systemu.
Skąd się to bierze
Komputer nie zna liter, zna liczby. Kodowanie znaków to umowa, która mówi, jaka liczba oznacza jaką literę. Przez lata każdy kraj miał swoją umowę: my miewaliśmy ISO-8859-2, Windows-1250 i Mazovię, Rosjanie swoje, Grecy swoje. Ten sam bajt oznaczał w Warszawie ogonek, a w Moskwie literę cyrylicy.
Krzaczki pojawiają się dokładnie wtedy, gdy tekst zapisano według jednej umowy, a odczytano według innej. Nic się nie zepsuło — dane są całe, tylko czytane po grecku.
UTF-8, czyli jedna umowa dla wszystkich
UTF-8 rozwiązał to raz na zawsze, przypisując unikalny numer każdemu znakowi świata — od łaciny po emoji. Dziś używa go ponad 98 procent stron internetowych. Ma jedną cechę, przez którą wygrał: zwykły angielski tekst wygląda w nim identycznie jak w starym ASCII, więc przejście na niego nie zepsuło niczego, co już działało.
Polskie litery zajmują w nim po dwa bajty, znak euro trzy, emoji cztery. Stąd bierze się najczęstsza pułapka: liczba znaków to nie to samo co liczba bajtów.
Trzy miejsca, w których warto to sprawdzić
- Strona. W sekcji
<head>musi być<meta charset="UTF-8">. Najlepiej jako pierwszy znacznik. - Pliki. Edytor musi zapisywać w UTF-8 — najlepiej bez BOM, bo ten niewidzialny znacznik na początku pliku potrafi wysypać nagłówki w PHP.
- Baza danych. Tu jest największa pułapka. Kodowanie o nazwie
utf8w MySQL to nie jest prawdziwe UTF-8 — obsługuje najwyżej trzy bajty na znak, więc emoji się w nim nie zmieści. Właściwa nazwa toutf8mb4. Połączenie z bazą też trzeba ustawić na to samo kodowanie.
Drobiazg, który ratuje opisy w Google
Skracanie tekstu zwykłym substr potrafi przeciąć polską literę na pół i zostawić w kodzie strony pytajnik w rombie. Do tekstów z ogonkami używaj wersji świadomych kodowania:
// źle — tnie po bajtach
substr($opis, 0, 160);
// dobrze — tnie po znakach
mb_substr($opis, 0, 160, "UTF-8");
Ta sama zasada dotyczy liczenia długości: strlen("żółw") zwróci 7, a mb_strlen("żółw", "UTF-8") — poprawne 4.
Ustaw UTF-8 wszędzie i konsekwentnie, a o krzaczkach zapomnisz na dobre.
Komentarze (6)
-
Sylwia
Ta pułapka z utf8 kontra utf8mb4 w MySQL kosztowała mnie kiedyś cały wieczór. Dobrze, że ktoś to wreszcie napisał wprost.
Odpowiedz -
Sylwia
Ta pułapka z utf8 kontra utf8mb4 w MySQL kosztowała mnie kiedyś cały wieczór. Dobrze, że ktoś to wreszcie napisał wprost.
Odpowiedz -
Bartek
Zajawka z tymi krzaczkami na początku to majstersztyk. Przewinąłem najpierw listę wpisów i myślałem, że coś się wam popsuło.
Odpowiedz