substr může uříznout polovinu znaku

16.9.2008(16:00) | Napsal: matej21 | Kategorie: PHP | Přečteno: 5070x

Možná se vám již stalo, že po oříznutí textu php funkcí substr, zobrazil nějaký "ošklivý" znak nebo otazník. Čím to je a jak to vyřešit?


pozn. přišel jsem na to sám, takže se zde mohou vyskytovat faktické nepřesnosti :)

Tak v čem je problém

Do situace, kdy místo prvního nebo posledního znaku v textu oříznutého funkcí substr uvidíte jen otazník, se můžete dostat pouze v případě, že používáte více jak osmi bitovou znakovou sadu. Takže pokud používáte například ISO8859-2 nebo Windows-1250, tak se do tohoto problému nedostanete. Problém nastává, jestliže používáte velmi častou sadu UTF-8. To sice základní znaky ukládá do osmi bitů, ale pokud napíšete nějaký např. český znak, tak se musí uložit do 16 bitů, neboli dvou bajtů. Ptáte se jak to souvisí s našim problémem?

Funkce substr neořezává řetězec - jak by se na první pohled zdálo - podle znaků, ale podle bajtů. Pokud chceme například slovo "něco" oříznout na 3 znaky bajty, tak v případě použité znakové sady UTF-8  dostaneme pouze "ně", protože znak "ě" se musí uložit do dvou bajtů. V případě ISO8859-2 pak dostaneme "něc", protože zde se znak "ě" vejde do jednoho bajtu. Větší problém je, když stejný řetězec chceme oříznout na 2 znaky. To se nám zobrazí pouze "n�" - což zrovna pěkné neni.

Jak to vyřešit

Při řešení tohoto pro mě napadlo zdrojový text převést do ISO8859-2, takže všechny znaky nyní budou mít pouze 1 bajt. Potom zkrátit funkcí substr a nakonec zase vrátit do UTF-8.

<?
$text
="Nějaký ukázkový text";
echo iconv("iso8859-2""utf-8"substr(iconv("utf-8""iso8859-2"$text),0,10));
?>

Při použití tohoto kódu dostaneme Nějaký uká. Pokud bychom použili jen samotné substr, vrátilo by se nám pouze Nějaký u

Update: proč to dělat jednoduše, když to jde složitě? Pro tento problém je zde stvořená funkce mb_substr :)


Komentáře k článku

Jméno:
Heslo:
Mail:
Web:
Vzkaz:
Spam kontrola:
napište číslo jedna
Smajlíci:
  Help
RSS tohoto článku: rss