Podstawy

Polskie znaki, krzaczki i UTF-8 w pigułce

12 sierpnia 2026 2 min czytania web-pc.pl 6 komentarzy

żół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.

Polskie znaki, krzaczki i UTF-8 w pigułce

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 utf8 w 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 to utf8mb4. 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.

Podziel się:

Komentarze (6)

  1. 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
  2. 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
  3. 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