Lekce 15 - Funkce pro práci s řetězci v PHP
V minulé lekci, Nejčastější chyby PHP nováčků - Umíš pojmenovat proměnné?, jsme si ukázali nejčastější chyby začátečníků v PHP ohledně pojmenování proměnných.
V dnešním PHP tutoriálu si ukážeme PHP funkce pro textové řetězce
Textové řetězce a UTF-8
Část PHP funkcí pro práci s řetězci začíná prefixem
mb_
. Je to z toho důvodu, že tyto funkce podporují UTF-8
kódování (MB jako MultiByte). V kódování UTF-8 se píše naprostá
většina webů, protože umí většinu znaků většiny národních abeced.
Není tedy problém na webu použít češtinu, dále citovat něco rusky nebo
používat speciální znaky jako ☺
nebo ♥
.
Většina IDE (např. NetBeans) tvoří projekty vždy jako UTF-8. Pokud UTF-8
nepoužíváte, setkáte se časem s velkými problémy, např. tehdy, když
budete chtít použít nějakou cizí knihovnu. Její autor totiž určitě
počítá s tím, že UTFko používáte.
Jakmile v aplikaci používáme tyto funkce, musíme často nejprve nastavit
kódování, jinak nebudou korektně fungovat ve starších verzích PHP.
Kódování stačí nastavit jen jednou v každém požadavku. Pokud se celý
váš web zobrazuje přes index.php
, jak jsme si zde ukazovali,
stačí nastavení vložit pouze na začátek indexu.
mb_internal_encoding("UTF-8");
Délka řetězce
Délku řetězce ve znacích získáme pomocí funkce
mb_strlen()
. Udělejme si malou ukázku, samozřejmě si nad ní
vložte ještě řádek výše, který nastaví kódování.
{PHP}
mb_internal_encoding("UTF-8");
$text = "Salvador Dalí";
$delka = mb_strlen($text);
echo("Text má $delka znaků.");
{/PHP}
Výstup:
V zastaralých učebnicích a tutoriálech naleznete použití
funkcí bez prefixu mb_
. Tedy místo mb_strlen()
jen
strlen()
. Tyto funkce nikdy nepoužívejte, jelikož neumí UTF-8 a
budou vám vracet špatný výstup. Např. znak Č
je v UTF
kódování uloženo jako 2
bajty (protože všechny znaky se do
jednoho bajtu prostě nevejdou). Funkce s prefixem mb_
bere
Č
jako jeden znak, funkce bez tohoto prefixu ho bere jako
2
znaky. Vrací tedy špatně délku řetězců s diakritikou a
nedokáže rozeznat o která písmena se jedná. PHP obsahuje z důvodu zpětné
kompatibility mnoho funkcí, které vícebajtová kódování nepodporují,
měli byste se vždy podívat, zda je funkce tzv. multibyte-safe a případně
najít její multibyte variantu.
Práce s podřetězci
Určitému úseku řetězce říkáme podřetězec. Ukažme si nějaké příklady s podřetězci, jelikož s těmi budeme často pracovat.
Zjištění pozice podřetězce
Pokud chceme zjistit, na jaké pozici se v řetězci nachází konkrétní
podřetězec nebo zda ho text vůbec obsahuje, použijeme funkci
mb_strpos()
. Abychom si to udělali zajímavější, budeme chtít,
aby nám nezáleželo na velikosti písmen. Z toho důvodu nejprve celý
řetězec převedeme na velká písmena pomocí funkce
mb_strtoupper()
a poté v něm budeme hledat podřetězec, též
velkými písmeny.
{PHP}
mb_internal_encoding("UTF-8");
$retezec = mb_strtoupper('Wolfgang Amadeus Mozart');
$podretezec = mb_strtoupper('amadeus');
if (mb_strpos($retezec, $podretezec) !== false)
echo("Nalezeno");
else
echo("Nenalezeno");
{/PHP}
Výstup:
Funkce mb_strpos()
vrací
hodnotu 0
, když že je podřetězec na první
pozici. Pokud nebyl podřetězec nalezen, vrací hodnotu
false
. Z tohoto důvodu je nutné výsledek porovnávat i s ohledem
na datový typ, jak jsme se to učili u podmínek. Jinak by byla hodnota
false
a 0
vyhodnocena stejně a program by hlásil,
že podřetězec nebyl nalezen i v případě, že by jím řetězec
začínal.
K funkci mb_strpos()
existuje ještě funkce
mb_strrpos()
(r
navíc jako reverse,
opačně), která funguje úplně stejně, jen vyhledává od konce
řetězce. Hodí se například při zjišťování přípony
souboru.
V problematice vyhledávání podřetězců se řetězci často říká kupka sena (haystack) a podřetězci jehla (needle).
Získání podřetězce podle pozice
Podřetězec získáme pomocí funkce mb_substr()
, která bere v
parametrech řetězec, index, od kterého podřetězec začíná a délku
podřetězce. Zkusme si to:
{PHP}
mb_internal_encoding("UTF-8");
$text = "Wolfgang Amadeus Mozart";
echo(mb_substr($text, 9, 7));
{/PHP}
Výstup:
Získali jsme podřetězec od 9. znaku, dlouhý 7 znaků.
Přístup k určitému znaku
S textovými řetězci lze v novějších verzích PHP pracovat jako s polem a to tímto způsobem:
{PHP}
mb_internal_encoding("UTF-8");
$hora = "Mount Everest";
echo($hora[0]);
{/PHP}
Podobného výsledku šlo docílit v minulosti i pomocí složených
závorek, ale tato syntaxe byla z PHP odstraněna. Kód výše vypíše 1. znak.
Bohužel tento způsob ještě nepodporuje vícebajtová kódování
jako UTF-8, a proto ho nepoužívejte. Pokud potřebujete přistoupit k
nějakému znaku, jednoduše jej získejte jako podřetězec pomocí výše
zmíněné funkce mb_substr($vstup, $pozice, 1)
.
Nahrazení podřetězce
V textu můžeme velmi jednoduše nahradit nějaký podřetězec jiným.
Docílíme toho použitím funkce str_replace()
a můžeme tak
jednoduše zabezpečit např. emailovou adresu před spamboty tak, že znak
zavináče nahradíme textem "(zavináč)"
. Roboti pak obvykle
nepoznají, že se jedná o email a nebudou vám nabízet výhodné půjčky
{PHP}
mb_internal_encoding("UTF-8");
$adresa = '[email protected]';
$osetrenaAdresa = str_replace('@', '(zavináč)', $adresa);
echo($osetrenaAdresa);
{/PHP}
Výstup:
Pokud by v textu bylo více takových podřetězců, funkce nahradí všechny.
Nahrazení podle slovníku
Pokud potřebujeme provést více nahrazení, PHP nabízí funkci
strtr()
(jako STRing TRanslate,
ano, pojmenování mnoha funkcí je v PHP velmi zavádějící). Funkce bere v
parametrech řetězec a slovník, kde jsou jako klíče podřetězce, které
chceme nahradit a jako hodnoty řetězce, kterými je chceme nahradit.
Funkce se často používala k nahrazení textových smajlíků v nějakém textu za HTML obrázky. Zkusme si to:
{PHP}
mb_internal_encoding("UTF-8");
$slovnik = array(
':)' => '<img src="images/img/smileys/happy.png" alt="úsměv" />',
':D' => '<img src="images/img/smileys/laughing.png" alt="smích" />',
);
echo(strtr('Ahoj :) Je mi fajn, protože jsem objevil ITnetwork :D', $slovnik));
{/PHP}
Výstup:
V dnešní době je však celá řada smajlíků a dalších emoji dostupná jako znaky Unicode, takže tento způsob zobrazování smajlíků je čím dál méně populární.
Rozdělení řetězce na pole podřetězců
Velmi užitečnou dvojicí funkcí jsou expresivně pojmenované
explode()
a implode()
. Funkce explode()
rozdělí řetězec na pole podřetězců pomocí určitého oddělovače.
Funkce implode()
naopak spojí podřetězce v poli do jednoho
dlouhého řetězce a mezi podřetězce vloží oddělovač. Oddělovači se
někdy expresivně říká lepidlo (glue).
Níže uvedený jednoduchý program bere na vstupu řetězec s několika čísly, které jsou oddělené čárkou. Z těchto čísel následně vypočítá součet:
{PHP}
mb_internal_encoding("UTF-8");
$vstup = "1,5,87,65,42,4,456,8,5,98,54,89";
$cisla = explode(',', $vstup);
echo(array_sum($cisla));
{/PHP}
Funkce explode()
rozdělí řetězec podle čárky a vrátí
pole jeho částí. Pomocí funkce array_sum()
následně získáme
součet prvků v poli. Pokud přicházíte z nějakého nízkého jazyka, asi se
divíte, jak je v PHP vše jednoduché. Je to z toho důvodu, že PHP je tzv.
vysoký jazyk. Právě díky tomu můžeme svou energii zaměřit na vývoj
aplikace a ne na řešení základních problémů.
PHP funkce pro práci s řetězci
Na závěr si uveďme seznam těch nejdůležitějších funkcí, které nám PHP pro práci s řetězci nabízí. Každou si můžete rozkliknout a podívat se, jak se používá. Opět je nemusíte umět nazpaměť, stačí vědět, že tam jsou a že si je v případě potřeby můžete vyhledat.
mb_internal_encoding | Nastavení kódování. |
mb_strlen | Získá délku řetězce. |
mb_strpos | Najde pozici prvního výskytu podřetězce v řetězci. |
mb_substr | Vrátí podřetězec od startovní pozice s určitým počtem znaků. |
mb_strtoupper | Převede všechna písmena v rětězci na velká. |
mb_strtolower | Převede všechna písmena v rětězci na malá. |
trim | Odstraní bílé místo na okolo řetězce. |
htmlspecialchars | Převede speciální znaky v textu na HTML entity. |
htmlspecialchars_decode | Převede entity v textu zpět na speciální znaky. |
strip_tags | Odstraní z daného řětězce HTML tagy. |
nl2br | Nahradí konce řádků (\n ) tagem
<br /> |
str_replace | Nahradí všechny výskyty podřetězce v řetězci daným podřetězcem. |
strtr | Přeloží podřetězce podle slovníku. |
parse_str | Rozbalí proměnné z textového řetězce ve tvaru QUERY stringu. |
explode | Převede řetězec na pole podřetězců. |
implode | Zabalí pole do textového řetězce. |
hash | Vypočítá otisk (hash) řetězce, což budeme potřebovat pro ukládání hesel. |
V následujícím cvičení, Řešené úlohy k 15. lekci PHP, si procvičíme nabyté zkušenosti z předchozích lekcí.