Lekce 15 - Tvorba vlastních funkcí v PHP
V minulé lekci, Datové typy v PHP, jsme si vysvětlili, jak fungují datové typy v PHP, co to je dynamické typování a jak funguje práce s různými datovými typy.
V dnešním PHP tutoriálu si ukážeme, jak vytvářet vlastní funkce.
Tvorba vlastních funkcí
Zatím jsme pouze používali cizí funkce. Není ovšem nic těžkého vytvořit si funkci vlastní. Rozdělování skriptů do funkcí má následující výhody:
- Přehlednost - Pokud se nějaký algoritmus skládá z více kroků, vytvoříme funkci pro každý tento krok a funkce potom voláme po sobě. Vezměme si např. náš emailový formulář z minulých lekcí. Ten zvalidoval zda bylo vše vyplněné a poté odeslal email. Vše bylo napsáno na jednom místě a zamotané do sebe. Správně bychom na daném místě měli volat jen funkci pro validaci a funkci pro odeslání. Každá funkce potom obsahuje jen to, co do ní patří. Kód se stává přehlednějším.
- DRY (neopakujme se) - Zkratka
DRY
označuje Do not Repeat Yourself, tedy neopakujte se. Jedná se o uznávaný programátorský princip, který odsuzuje duplikovaný kód. Pokud chceme nějakou část kódu použít vícekrát, nemusíme ji opisovat, ale oddělíme ji do funkce. Poté pouze zavoláme jednu funkci na více místech programu. Když potom chceme v kódu něco opravit, nehledáme chybu na několika místech, ale opravíme ji jen v té jedné funkci. - Možnost použití knihoven - Funkce, které často používáte, můžete vkládat do samostatných souborů, kterým se někdy říká knihovny (anglicky library). Pokud si vytvoříte např. knihovnu pro přihlašování uživatelů, můžete ji potom jen vložit do jiného projektu, načíst a začít používat dané funkce, aniž byste něco znovu programovali.
Pozn.: V dalších seriálech si ukážeme i jak členit funkce do objektů. Dosáhneme tím opravdu velmi čitelného kódu, který lze navíc rozšiřovat.
Správný program by měl být poskládaný z několika kratších funkcí,
neměl by vypadat jako dlouhá nudle kódu
Jednoduchá funkce
Vytvořme si úplně jednoduchou funkci, která jen něco vypíše. Funkci
deklarujeme pomocí klíčového slova function
. Za ním následuje
název funkce (ten by měl být psaný v camelCase) a závorky. Tělo funkce je
potom vloženo do bloku ze složených závorek.
Funkce by se měla jmenovat podle toho, co dělá. Měla by také dělat vždy jen jednu věc a pokud potřebujeme udělat 2 věci, vytvoříme si na to 2 funkce. Jako název funkce se mi osvědčilo používat sloveso v rozkazovacím způsobu (imperativu). Jakmile funkci někde deklarujeme, můžeme ji níže volat. Uděláme to jednoduše napsáním jejího názvu a závorek.
Následující kód vložíme kamkoli do PHP sekvence:
{PHP}
function pozdrav()
{
echo('Vítejte na mém webu');
}
pozdrav();
{/PHP}
Výsledek:
Nahoře deklarujeme funkci, níže hotovou funkci zavoláme.
Funkci musíme pochopitelně vždy deklarovat nad místem, odkud ji voláme. PHP parsuje zdrojový kód od začátku do konce, a pokud bychom to udělali naopak, narazilo by na volání funkce, o které si ještě "nepřečetlo".
Funkce s parametry
Funkci samozřejmě můžeme vložit i nějaké parametry. Na jednoduchém příkladu si ukažme funkci, která vypíše součet dvou čísel. Takto triviální funkci bychom v praxi sice nedeklarovali, ale jako příklad poslouží dobře a reálnou funkci si ukážeme na konci. Parametry vkládáme jako proměnné do závorky v hlavičce funkce a oddělujeme je čárkou:
function secti($a, $b) { $soucet = $a + $b; echo("Součet: $soucet"); }
Funkci následně voláme takto:
{PHP}
function secti($a, $b)
{
$soucet = $a + $b;
echo("Součet: $soucet");
}
secti(10, 20);
{/PHP}
Při volání funkce můžeme do parametrů samozřejmě vložit i proměnné:
$a = $_POST['cislo1']; $b = 20; secti($a, $b);
Z funkcí nelze přistupovat k nějaké proměnné, která je definována
mimo funkci. Ve funkci můžete přistupovat jen k proměnným, které přišly
v parametru a maximálně k superglobálním polím, jako jsou
$_GET
a $_POST
. Sice to jde obejít pomocí
klíčového slova global
, ale to nedělejte, jelikož taková
funkce ztrácí smysl. Když něco nejde, má to většinou nějaký smysl a
neměli bychom hledat způsob, jak obejít zákaz, ale jak to udělat správně
Vše, co funkce potřebuje,
jí jednoduše předáme ve vstupních parametrech.
Funkce s návratovou hodnotou
Funkce může také vracet nějakou hodnotu. V ukázkách výše jsme ve
funkcích pouze vypisovali. V praxi se takovéto funkce příliš nepíší,
jelikož nejsou univerzální. Představte si, že nechceme součet vypsat, ale
použít ho jako mezivýsledek při dalším výpočtu. Proto funkce
výslednou hodnotu většinou vrací. Tam, kde byla funkce volána, si
s ní potom můžeme udělat co chceme. Funkce může vždy vrátit jen
jednu hodnotu a jakmile ji vrátí, tak se na tom místě
ukončí a další kód v ní se již neprovede. Hodnotu
vracíme pomocí klíčového slova return
.
Pokud potřebujeme vrátit více hodnot, můžeme vrátit pole, nebo si pro každou hodnotu vytvořit samostatnou funkci. Záleží na konkrétním případu.
Upravme naší sčítací funkci tak, aby výsledek místo vypisování vracela:
function secti($a, $b) { $soucet = $a + $b; return $soucet; }
Funkci bychom poté volali takto:
{PHP}
function secti($a, $b)
{
$soucet = $a + $b;
return $soucet;
}
$soucet = secti(10, 20);
echo("Součet: $soucet <br />");
echo("Dvojnásobek součtu: " . ($soucet * 2));
{/PHP}
Vidíte, že když naše funkce hodnoty vrací, je naprosto univerzální a můžeme ji použít jak k výpisu, tak k další práci. Výsledek můžeme později uložit třeba do databáze, souboru, kamkoli.
Od PHP verze 7 byly přidané datové typy. Můžeme tak do parametru metody specifikovat, jaký má mít parametr datový typ. Jaký datový typ metoda vrací, lze také specifikovat.
Ukažme si to na stejném příkladu. Jelikož chceme, ať jde sečíst jak
celé, tak i desetinné, uvedeme datový typ float
. Funkce bude
taktéž vracet float
:
function secti(float $a, float $b) : float { $soucet = $a + $b; return $soucet; }
A volali bychom ji stejně, jen s desetinným číslem:
function secti(float $a, float $b) : float { $soucet = $a + $b; return $soucet; } $soucet = secti(5.333, 4.111); echo("Součet: $soucet <br />"); echo("Dvojnásobek součtu: " . ($soucet * 2));
Výstup:
Můžeme klidně změnit návratový typ metody na int
(celé
číslo):
function secti(float $a, float $b) : int { $soucet = $a + $b; return $soucet; } $soucet = secti(5.333, 4.333); echo("Součet: $soucet <br />"); echo("Dvojnásobek součtu: " . ($soucet * 2));
Výsledek je možná znepokojující:
Součet čísel 5.333
a 4.333
je
9.666
, čili by to mělo být správně zaokrouhleno nahoru na
číslo 10
, jenže v tomto případě tomu tak není! Metoda
vrátí pouze celé číslo, klidně tedy číslo 9
při výsledku
9.99999999
!.
Striktní typy
Za normálních podmínek můžeme do parametrů metody secti()
předávat hodnoty jakýchkoliv datových typů. Klidně i string
(textový řetězec). Kalkulačka nám výsledek klasicky spočítá, i když to
nedává úplně smysl.
Změna nastává, pokud na začátku souboru deklarujeme striktní typy. Zkusme si tedy nad metodu napsat tento řádek:
declare(strict_types=1);
Díky tomuto řádku se nám již nestane nelogické sčítání čísla a například textového řetězce.
Zkusme si to na příkladu:
declare(strict_types=1); function secti(float $a, float $b) : float { $soucet = $a + $b; return $soucet; } $soucet = secti(5.333, "5 textů"); echo("Součet: $soucet <br />"); echo("Dvojnásobek součtu: " . ($soucet * 2));
Vyvoláme fatal error a skript pokračovat nebude:
Funkce na odesílání emailu
Jako velmi užitečná funkce je funkce k posílání emailů. Nyní máme již dostatek znalostí k tomu, abychom si takovou funkci napsali. Když se podíváme zpět na kód k odeslání emailu v našem formuláři, dáme dohromady následující funkci:
function odesliEmail(string $adresa, string $predmet, string $odesilatel, string $zprava) { $hlavicka = 'From:' . $odesilatel; $hlavicka .= "\nMIME-Version: 1.0\n"; $hlavicka .= "Content-Type: text/html; charset=\"utf-8\"\n"; $uspech = mb_send_mail($adresa, $predmet, $zprava, $hlavicka); return $uspech; }
Funkce bude mít vvšechny parametry typu string
, jelikož se
jedná o textové řetězce. Funkce si připraví hlavičku na základě
vstupních parametrů a tu potom předá funkci mb_send_mail()
,
která email odešle. Tato funkce vrátí hodnotu 0
/1
podle toho, zda bylo odeslání úspěšné či nikoli. Toto hodnotu potom
vrátíme i naši funkci.
Volání funkce bude následující:
$uspech = odesliEmail('[email protected]', 'Test emailu', '[email protected]', 'Text zprávy'); if (!$uspech) echo('Email se nepodařilo odeslat, zkontrolujte adresu a odesílatele');
Určitě uznáte, že psát těch 5 řádků, co je nyní ve funkci, na
každém místě, kde potřebujeme odeslat email, je minimálně zdržující a
nepřehledné. Takhle napíšeme jen jeden řádek. Funkce však funguje jen v
tom souboru, ve kterém je deklarována. Můžete si také vyzkoušet odeslat
email na číslo 5
a nebo dát text zprávy jako integer (taky
třeba 5
). Pokud máme stále deklarované striktní typy
(declare(strict_types=1)
), volání funkce se nezdaří a vyvolá
to zase fatální chybu.
V následujícím cvičení, Řešené úlohy k 14. lekci PHP, si procvičíme nabyté zkušenosti z předchozích lekcí.
Komentáře


Zobrazeno 10 zpráv z 14. Zobrazit vše