Lekce 6 - Tagy v textovém řetězci
V předchozí lekci, Nahrazování textových řetězců, jsme si vysvětlili, jak nahrazovat textové řetězce pomocí PHP funkcí.
V této lekci kurzu PHP funkcí si vyjmenujeme a detailně popíšeme funkce pro práci se značkami (tagy), jejich odstraňování a konvertování.
Můžeme se dostat do situace, kdy se v našem textovém řetězci
potřebujeme zbavit nechtěných tagů a nebo je zobrazit tak, aby se
nepřekládaly do HTML, XML či
PHP. Také nechtěná zpětná lomítka nám mohou v našem
kódu udělat pěknou neplechu. Funkce, které si zde popíšeme, nám usnadní
práci s dlouhým vyhledáváním a přepisováním tagů nebo nevhodně
umístěných zpětných lomítek. Například funkce
htmlspecialchars()
je hojně využívaná jako obrana proti
útoku XSS a jiných. Je dobré tedy alespoň tuto funkci znát
strip_tags()
V PHP je funkce, která nám z textového řetězce jednoduše odstraní
HTML, PHP či XML tagy. Funkce strip_tags()
přijímá 2 parametry,
kde první z nich je textový řetězec a druhý je tag, který se může v
textovém řetězci vyskytovat a nebude smazán, není však povinný. Příklad
funkce strip_tags()
:
$text = "Toto je <a href='www.google.cz'><h1>Nadpis</h1></a> první úrovně"; print(strip_tags($text));
V textovém řetězci jsou odstraněny všechny HTML tagy a na stránce bude vypsán text bez tagů:
Avšak pokud přidáme do druhého parametru některé HTML tagy, nebudou odstraněny:
$text = "Toto je <a href='www.google.cz'><h1>Nadpis</h1></a> první úrovně"; print(strip_tags($text, '<h1>'));
Nyní jsme do funkce strip_tags()
přidali tag nadpisu první
úrovně. Tento tag se neodstraní a bude viditelný na stránce. Druhý tag
<a>
v našem textovém řetězci ale odstraněn bude:
Od verze PHP 7.4.0 lze tagy u druhého parametru zapisovat do hranatých závorek, výstup na stránku bude stejný:
$text = "Toto je <a href='test'><h1>Nadpis</h1></a> první úrovně"; print(strip_tags($text, ['h1', 'a']));
Pokud bychom chtěli odstranit více tagů najednou a nemáme PHP verzi 7.4.0, můžeme více tagů odstranit takto:
$text = "Toto je <a href='test'><h1>Nadpis</h1></a> první úrovně"; print(strip_tags($text, '<h1><a>'));
Výstup bude stejný jako předchozí příklad.
stripslashes()
Funkce stripslashes()
odstraňuje zpětná lomítka
\
i u speciálních znaků například \n
. Odstraňuje
také znaky přidané funkcí addslashes()
. Funkce přijímá pouze
jeden parametr, kterým je náš textový řetězec:
$text = "Programovací jazyk \PHP \n je úžasný!"; print(stripslashes($text));
Zpětná lomítka jsou odstraněny, jelikož náš textový řetězec je
napsaný v uvozovkách ""
, bude speciální znak \n
proveden a lomítko nebude odstraněno. Výstup na stránce bude:
Speciální znak \n
se provedl, avšak nový řádek se
většinou vytvoří pouze v konzoli. Když si tedy soubor spustíme v konzoli
pomocí PHP, budeme mít tento výstup:
C:\wamp\www> php .\stripslashes.php Programovací jazyk PHP je úžasný!
Pokud zapíšeme textový řetězec do apostrofů ''
, zpětné
lomítko u speciálního znaku \n
bude odstraněno:
$text = 'Programovací jazyk \PHP \n je úžasný!'; print(stripslashes($text));
Na stránce uvidíme:
stripcslashes()
Je podobná funkci stripslashes()
. Odstraňuje zpětná lomítka
\
. Rozdílem je, že u speciálních znaků, například
\n
, lomítko neodstraní a znak bude proveden. Odstraňuje také
znaky přidané funkcí addcslashes()
. Funkce přijímá pouze
jeden parametr, kterým je náš textový řetězec:
$text = 'Programujeme\ v jazyce \n PHP'; print(stripcslashes($text));
Zpětná lomítka v textu budou odstraněny, výjimkou jsou však speciální
znaky \n
které budou provedeny:
Na stránce nový řádek zase pravděpodobně neuvidíme, v konzoli by ale věta bylo odřádkována takto:
Programujeme v jazyce PHP
htmlspecialchars()
Konvertuje speciální znaky na HTML entity. Tagy tudíž nebudou přeloženy
do HTML, ale budou zobrazeny jako klasický text. Například typický HTML tag
pro tučný styl písma <b>
bude konvertován pomocí HTML
entit a na stránce zobrazen jako text:
$text = 'Tento text má být zobrazen <b>tučně</b>'; print(htmlspecialchars($text));
Výsledkem na stránce bude:
Avšak část textu zobrazena tučně není. Tagy <b>
a
</b>
jsou přeloženy jako HTML entity
<b>
a </b>
, tudíž jejich
vlastnost bude vynechána.
Překládá pouze určité znaky, které jsou zapsány v tabulce:
Znak | Překlad |
---|---|
& - ampersand |
& |
" - uvozovka |
" , pokud není stanovena vlajka
ENT_NOQUOTES |
' - apostrof |
' , pouze pokud je stanovena vlajka
ENT_QUOTES |
< - menší než |
< |
> - větší než |
> |
Funkce htmlspecialchars()
přijímá kromě našeho textového
řetězce ještě další 3 parametry. Druhým parametrem jsou
tzv. vlajky (flags), které určují, jak zacházet s
uvozovkami, neplatným kódováním a použitým typem dokumentu. Pro
zacházení s uvozovkami zde existují tyto flagy:
Vlajka | Popis |
---|---|
ENT_COMPAT |
Nepřeloží apostrofy, uvozovky ano |
ENT_QUOTES |
Přeloží uvozovky a apostrofy |
ENT_NOQUOTES |
Nepřeloží uvozovky ani apostrofy |
Flagů však existuje více, všechny si je ukazovat ale nebudeme.
Uveďme si příklad:
$text = "Pavel & Jana jsou 'dobří' přátelé"; print(htmlspecialchars($text, ENT_COMPAT)); echo "<br>"; // všimněte si uvozovek $text = 'Pavel & Jana jsou "dobří" přátelé'; print(htmlspecialchars($text, ENT_COMPAT));
Flag ENT_COMPAT
uvozovky a jiné speciální znaky nebo tagy
přeloží jako HTML entity, apostrofy však přeloženy nebudou. Po zobrazení
zdrojového kódu stránky uvidíme tedy tyto dvě věty:
Pavel & Jana jsou 'dobří' přátelé Pavel & Jana jsou "dobří" přátelé
Flag ENT_QUOTES
přeloží všechny speciální znaky včetně
uvozovek do HTML entit:
$text = "Pavel & Jana jsou 'dobří' přátelé"; print(htmlspecialchars($text, ENT_QUOTES));
Ve zdrojovém kódu stránky můžeme vidět tento výsledek:
Pavel & Jana jsou 'dobří' přátelé Pavel & Jana jsou "dobří" přátelé
Flag ENT_NOQUOTES
přeloží všechno, kromě uvozovek a
apostrofů:
$text = "Pavel & Jana jsou 'dobří' přátelé"; print(htmlspecialchars($text, ENT_NOQUOTES));
Ve zdrojáku můžeme vidět zachované apostrofy:
Pavel & Jana jsou 'dobří' přátelé
Třetí parametr specifikuje kódování
(encoding) našeho textového řetězce. Defaultně je
nastavené kódování na UTF-8
. Kódování funkce
htmlspecialchars()
můžeme změnit na ISO-8859-1
takto:
$text = 'Změna kódování na ISO-8859-1'; print(htmlspecialchars($text, ENT_COMPAT, "ISO-8859-1"));
Čtvrtým parametrem je tzv. dvojité kódování
(double encode). Defaultní hodnota je true
,
tudíž se konvertují všechny speciální znaky a tagy. Pokud tedy do našeho
textového řetězce vložíme HTML entitu, například &
,
nebude znova přeložena na znak ampersandu &
:
$text = 'Znak ampersandu & je zapsán jako HTML entita takto: &'; print(htmlspecialchars($text, ENT_COMPAT, "UTF-8", true)); // HTML entitu přeložíme dvakrát
První ampersand v textovém řetězci je přeložen na HTML entitu
&
a na stránce ho můžeme vidět jako znak
&
. HTML entita &
v našem textovém
řetězci je znova přeložena a je zapsána jako
&amp;
:
Pokud však u čtvrtého parametru zvolíme hodnotu
false
, je první ampersand v textovém řetězci přeložen úplně
stejně, jako u prvního případu. Druhý ampersand zapsaný pomocí
HTML entity je však přeložen na znak ampersandu:
$text = 'Znak ampersandu & je zapsán jako HTML entita takto: &'; print(htmlspecialchars($text, ENT_COMPAT, "UTF-8", false)); // HTML entita bude zobrazena jako znak
Výsledkem bude:
Funkce htmlspecialchars()
překládá pouze znaky
ze zadané tabulky výše. Pokud však chceme překládat všechny HTML entity,
použijeme funkci htmlentities()
, která přijímá stejné
parametry.
htmlspecialchars_decode()
Funkce htmlspecialchars_decode()
je obráceným způsobem funkce
htmlspecialchars()
. Konvertuje HTML entity na speciální znaky,
které mohou tvořit jednotlivé tagy v HTML. Textový řetězec napsaný
pomocí HTML entit <b>tučný text</b>
je tedy přeložen zpět na speciální znaky
<b>tučný text</b>
. Tagy <b>
a
</b>
budou tudíž platné a textový řetězec bude mít
styl tučného písma:
$text = "<b>tučný text</b>"; print(htmlspecialchars_decode($text));
Na stránce uvidíme:
HTML entity v textovém řetězci jsou tedy zpět přeloženy (dekódovány) na speciální znaky.
Funkce htmlspecialchars_decode()
ještě 2. parametr. Prvním z
nich je tedy náš textový řetězec a druhým parametrem jsou vlajky
(flags), které jsou úplně stejné jako u funkce
htmlspecialchars()
. Ukažme si příklad s druhým parametrem:
$text = "<h1>Nadpis první úrovně</h1> a další 'text'"; print(htmlspecialchars_decode($text, ENT_COMPAT)); // HTML entity budou přeloženy jako uvozovky a jiné speciální znaky nebo tagy.
V prohlížeči, při zobrazení zdrojového kódu stránky, je textový řetězec napsán takto:
<h1>Nadpis první úrovně</h1> a další 'text'
Na stránce jinak klasicky uvidíme:
Podobnou funkcí k htmlspecialchars_decode()
je
funkce html_entity_decode()
, avšak stejně jako opačná funkce
htmlentities()
překládá všechny ostatní znaky, zatímco
htmlspecialchars_decode()
je omezena rozsahem překládaných
znaků.
nl2br()
Je funkce, která vkládá HTML tagy <br>
nebo
<br />
pro zalomení řádku místo znaku pro nový řádek
\n
v textovém řetězci. nl2br()
přijímá celkem 2
parametry, kde prvním parametrem je náš textový řetězec a druhým
parametrem je hodnota boolean, která rozhoduje, zda text bude zalamován HTML
tagem <br>
nebo XHTML tagem <br />
.
Ukažme si příklad:
$text = "První řádka textu.\nDruhá řádka textu."; print(nl2br($text));
Funkce nl2br()
místo znaku pro novou řádku \n
vloží HTML tag <br>
. Na stránce tedy uvidíme:
Pokud bychom si otevřeli zdrojový kód, viděli bychom takový výstup:
První řádka textu.
<br>
Druhá řádka textu.
$text = "První řádka textu.\nDruhá řádka textu."; print(nl2br($text, true));
Jestliže přidáme druhý parametr o hodnotě boolean true
,
bude pro novou řádku místo \n
vložen XHTML tag
<br />
. Na první pohled text bude zalomen stejně jako u
prvního příkladu. Ve zdrojovém kódu ale uvidíme rozdíl:
První řádka textu. <br /> Druhá řádka textu.
Pro takové nahrazování se stále častěji využívá funkce
str_replace()
, kterou jsme si vysvětlovali v lekci Nahrazování
textových řetězců
V další lekci, Vlastnosti textových řetězců a práce s mezerami, si ukážeme, jak zjistit vlastnosti textových řetězců a jak pracovat s mezerami pomocí funkcí v PHP.