jesteś w: Główna > PHP > Kodowanie UTF-8
Ostatnia aktualizacja tej strony: 2007-01-03, 22:01:54

UTF-8 i problemy w PHP oraz Flash - BOM (Byte Order Mark)

Ale o co chodzi z tym BOM?

Problem 1: przy kodowaniu stron w UTF-8 i dołączaniu ich do innego dokumentu przy pomocy PHP (np. instrukcją include, require lub porzez wczytywanie pliku fopen()) pojawia się pusta linia lub ciąg dziwnych znaków. Często usługa walidacyjna XHTML pokazuje komunikat, że dana linia nie może być odczytana.

Problem 2: plik tekstowy utworzony w PHP i wczytany do Flasha nie jest pokazywany poprawnie - brak polskich liter.

Oba problemy są spowodowane przez budowę pliku zakodowanego w UTF. Ja kodowałem UTF-8. Plik zakodowany w ten sposób może (ale nie musi) zawierać nagłówek "Byte Order Mark" czyli BOM. W przypadku UTF-8 są to trzy znaki o wartościach ef bb bf, co jest zupełnie nieistotne. Istotne jest to, że znaki są trzy.

Problem pierwszy wynika z tego, że większość przeglądarek nie interpretuje poprawnie tych znaków i chociaż widnieją one w źródle strony to na ekranie ich nie widać. Rozwiązaniem jest używanie edytora, który nie dodaje tego nagłówka (np. SciTE, z ustawioną opcją zapisu "UTF-8 cookie").

Drugi problem jest ciut trudniejszy do rozwiązania. Wydaje się, że flash wymaga nagłówka BOM, ale PHP tworząc plik tekstowy go nie dodaje (chociaż jeśli zmienne zostaną przesłane z Flasha do PHP i dopiero zostanie stworzony plik tekstowy to wszystko działa). Wyjściem jest zastosowanie takiego tricku, który przekonweruje wcześniej podane znaki ef bb bf na ciąg ASCII i zapisze do pliku.

<?php
$doPliku = "tekst, który ma być w pliku i zażółcić gęślą jaźń";
$doPliku = chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF')) . $doPliku; //dodaj BOM

$file=fopen("plik.txt", "w");
fwrite($file, $doPliku);
fclose($file);
?>

To, że plik zawiera trzy dodatkowe znaki łatwo sprawdzić. Wystarczy utworzyć w notatniku i zapisać jako UTF-8 plik bom.txt z krótką treścią:

<php 
//plik bom.txt zawiera treść "x"
$tmp=fread(fopen("bom.txt", "r"), filesize("bom.txt"));
echo strlen($tmp);
//strlen zwraca ilość znaków w ciągu
//ponieważ plik ma tylko literkę "x" strlen powinno zwrócić 1
//tymczasem zwraca 4
?>

lub utworzyć plik z treścią zerową i sprawdzić jego rozmiar.

Drugi sposób można także wykorzystać do załączania dokumentów do stron PHP (zamiast przez np. include) - wystarczy załadować plik do zmiennej, wyrzucić pierwsze trzy znaki i zrobić "echo $zmienna".

Więcej o BOM

Znaki ef bb bf występują w pliku zakodowanym w UTF-8. Żeby było śmieszniej inne kodowania UTF mają inny BOM. Zobacz BOM dla innych kodowań niż UTF-8 w Wikipedii.

RemoveBOM_utf8()

string removeBOM_utf8(string);

Pozwoliłem sobie popełnić taką małą funkcję, która obcina z początku stringu BOM (jeśli takowy występuje)

function removeBOM_utf8($s){
if(substr($s,0,3)==chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF'))){
return substr($s,3);
}else{
return $s;
}
}

Menu

Działy:

Quick start:

Inne:

animacje Flash

Diablo 2: