Funkcie
V tejto kapitole si preberieme opäť jednu zo štandardných praktík programovania a to je využívanie funkcií. Písanie funkcií zjednodušuje prácu programátora počas programovania, sprehľadňuje samotný kód a navyše má aj veľmi šikovné univerzálne využitia. Naučíme sa ich písať a ukážeme si tri hlavné dôvody, prečo je dobré ich používať.
V predchádzajúcich kapitolách sme často hovorili o tom, že by sa žiadny kód nemal opakovať, resp. že by kód programu nemal obsahovať dva a viac rovnakých riadkov, pretože je to neefektívne a zbytočné. Doteraz sme si ukázali napríklad cyklus alebo premenné, ktoré v istých momentoch vedia tento problém vyriešiť. Práve tento problém vie v akomkoľvek prípade vyriešiť použitie funkcie. Čo to teda tá funkcia je? Funkcia, ako vyplýva z jej názvu, je niečo, čo má niečo vykonať, vo väčšine príkaz alebo viac príkazov. Funkcia je akokeby bublina, do ktorej vieme vložiť jeden alebo viacej príkazov. Pri vytvorení a vložení príkazov do tejto bubliny sa dané príkazy nevykonajú, iba sme ich do nej vložili a okrem toho zadefinujujeme aj pre danú bublinu meno. Následne môžeme kdekoľvek, kedykoľvek a ľubovoľne veľakrát v programe (na hocijakom riadku) pomocou zavolaním (napísaním) mena tejto bubliny, túto bublinu zavolať (call – volať). Zavolaním tejto bubliny – funkcie, sa dané príkazy v nej vykonajú od hora dole, presne ako keby na danom riadku miesto volania funkcie boli všetky príkazy pod sebou vypísané. Vytváranie (deklarovanie) funkcie je nasledovné. Zadefinuje sa kľúčové slovo function, za ktorým nasleduje medzera a za ňou meno našej funkcie. Za menom nasledujú prázdne okrúhle zátvorky, za ktorými nasleduje štandardne dvojica množinových zátvoriek, do ktorých píšeme príslušné príkazy, podobne ako napríklad pri cykle alebo podmienke. Volanie funkcie sa vykoná zavolaním jej mena s prázdnymi okrúhlymi zátvorkami, za ktorými nasleduje bodkočiarka:
<?php
//vykonanie prikazov bez funkcie
$meno1 = "Jurko";
echo $meno1;
echo "<br>";
//deklaracia funkcie
function nasaFunkcia(){
$meno2 = "Misko";
echo $meno2;
echo "<br>";
}
nasaFunkcia(); //zavolanie funkcie
nasaFunkcia(); //zavolanie funkcie
Ako je vidieť v ukážke, najprv sme vykonali príkazy štandardne a následne sme si vytvorili funkciu s názvom nasaFunkcia. V jej vnútri/tele (telo – body) sme vytvorili premennú, vypísali sme jej obsah a za tým sme vypísali prázdny riadok. Následne sme ju v kóde zavolali za sebou dva razy. Na začiatku sme si vraveli, že program napísaný v jazyku PHP ide od hora dole a zaradom vykonáva jednotlivé príkazy. Toto je prípad, kedy sa toto troška modifikuje. Ak dojde program na riadok, kde sa volá funkcia, akokeby jeho ukazovateľ (index – aktuálne miesto v programe) preskočí na začiatok tejto funkcie a začnú sa vykonávať príkazy od hora dole až po jej koniec. Potom sa vráti naspäť na riadok volania funkcie. Je nutné upozorniť, že logicky nemôžeme volať funkciu skorej, ako bolo zadeklarovaná, pretože ju program nepozná, keďže ide kód od hora dole.
Kód programu alebo jednotlivých webstránok býva vo väčšine dlhý, obsahuje najmenej pár desiatok riadkov, niekedy aj pár stovák riadkov kódu. Predstavte si, že takmer každý riadok kódu má nejaký význam, niečo robí, niečo zapríčiňuje. Aby bol takýto kód prehľadnejší a aby sa v ňom dalo vyznať a lepšie s ním pracovať, je veľmi dobré naučiť sa správne používať funkcie. Programovanie ako také je v podstate písanie kódu na vyriešenie nášho problému, resp. požiadaviek (zadanie). Toto zadanie je komplexné a má jasný cieľ. Úlohou programátora je vedieť tento problém rozdeliť na jednotlivé časti, ktoré následne za sebou pôjdu a budú medzi sebou komunikovať, na menšie problémy a každú tú jednu časť rozdeliť na ešte menšie kúsky, až do momentu, kedy jeden kúsok bude predstavovať jeden riadok. Nejaké tie menšie časti (etapy) programu, ktoré majú spoločný cieľ, je dobré dávať do samostatných funkcií. Keď si takto program rozdelíme na viacej podprogramov, každý podprogram bude jedna funkcia, už len podľa jej názvu (nie to ešte ak má aj správny komentár pri svojej deklarácii) bude všetkým jasné, na čo slúži. Takýto program môže vyzerať tak, že na začiatku sa nadefinujú na jednom mieste funkcie, ktoré sú v danom programe nutné a na konci sa zaradom zavolajú. Deklarovať funkcie na jednom mieste je dobrá praktika, takisto je zvyk na začiatku programu na jednom mieste deklarovať všetky premenné, ktoré sa budú používať v programe. Takto je to oveľa prehľadnejšie a praktickejšie. Predstavte si, že by ste mali v celom programe kade tade deklarácie funkcií, premenných, vykonávanie príkazov...bol by to jeden neprehľadný guláš a bolo by veľmi ťažké prečítať, čo každá časť programu robí. Skúsime si to názorne ukázať v nasledujúcej ukážke, aby ste to pochopili. Predstavme si veľmi bežný prípad, že máme napísať program, ktorý zabezpečí správne zaregistrovanie používateľa na stránke. Mohlo by to vyzerať nejak takto:
<?php
//deklarovane premenne na zaciatku programu
$prihlasovacie_meno = "";
$heslo = "";
$email = "";
$uz_existuje = false;
//fcia, ktora nam zachyti vstup od pouzivatela
function nacitajVstupy(){
$prihlasovacie_meno = "Zadane_meno";
$heslo = "Zadane_heslo";
$email = "Zadany_email";
}
//fcia, ktora zisti, ci uz dany email nemame zaregistrovany
function testDuplicity(){
//kod, ktory by zistil z databazy, ci uz existuje
//a do $uz_existuje by ulozil odpoved
}
//fcia pri nespravnom registrovani
function vypisError(){
echo "Nepodarilo sa prihlasit. Email uz existuje.";
//dalsi kod, ktory by sa spustil pri nezaregistrovani
}
//fcia, ktora by uspesne zaregistrovala
function zaregistruj(){
/*kod, ktory by ulozil do databazy noveho usera
dalsi kod, ktory by ho napriklad presmeroval do profilu
*/
echo "Ste registrovany, Ggratulujeme!";
}
//chod programu
nacitajVstupy();
testDuplicity();
if(uz_existuje){
zaregistruj();
}else{
vypisError();
}
V poslednej ukážke sme samozrejme nenaprogramovali ozajstné registrovanie používateľa, len sme si spravili akokeby takú šablónu, ako by teoreticky mohla vyzerať táto časť programu. Je to logicky rozdelené, prehľadné a spĺňa to cieľ a požiadavky. Keď sa programátor, ktorý kód vytvoril alebo niekto cudzí, pozrie na kód, je mu hneď jasné, aké premenné sa tam používajú a ak je k nim aj komentár, bude hneď vedieť, na čo sú určené. Na konci zase vidí, aké funkcie v akom poradí sa spúšťajú a už len názov a komentáre mu veľa povedia, čo sa tam asi robí. Ak si to chce prejsť detailnejšie riadok po riadku, pozrie si funkcie a je to.
Možno vás napadlo, prečo dávame prázdne zátvorky za názvom funkcie, na čo je to dobré. Práve pri vysvetľovaní tejto tretej výhody používania funkcií na to spolu prídeme. Pri popisovaní funkcií sme spomenuli niečo o univerzálnosti funkcií. Zatiaľ sme si deklarovali funkcie, v ktorých bol kód jasne určený, vykonával predom dané príkazy s danými hodnotami vo vnútri funkcie. Za žiadnych okolností sme nemohli ovplyvniť niečím chod danej funkcie, správanie príkazov v nej definovaných a takisto hodnoty (premenné), s ktorými sa pracovalo v jej vnútri. Ak by to bolo iba takto, tak by to až tak veľmi efektívne nebolo. Funkcie by v tom prípade slúžili len na prerozdelenie kódu do jednotlivých častí (funkcií).
Predstavme si, že v našom programe potrebujeme vypisovať nejaký text a potrebujeme v ňom viackrát osloviť danú osobu, čiže vypísať text Vážený pán a Vážená pani, za ktorým by napríklad mali nasledovať dva prázdne riadky. Aby sme neopakovali ten istý príkaz, mohli by sme mať na to dve funkcie, pre každé oslovenie jednu funkciu samostatne. Predstavte si ale, aké by bolo šikovné, keby sme na to mohli mať iba jednu funkciu, ktorá by sa mohla volať vypisOslovenie a nejako by sme jej povedali, kedy má osloviť pána a kedy dámu. Nemuseli by sme mať zbytočne dve funkcie a oslovenie by sme mali vyriešené jednou. No a presne toto je možné pomocou parametrov funkcie (argumentov). Čo to je?
Pri volaní funkcie je možné do zátvoriek zadať hodnoty (ľubovoľný počet hodnôt oddelených čiarkou), napríklad stringy alebo integery. Počas zavolania funkcie sa tieto hodnoty akokeby posielajú do funkcie. Na začiatku funkcie ich môžeme odchytiť a to tak, že v zátvorkách pomenujeme premenné, ktoré budú tieto hodnoty reprezentovať. Následne sa tie hodnoty do daných premenných uložia (pri spustení funkcie) a počas vykonávania tela funkcie ich môžeme používať. A ako nám to pomôže? No pomôže nám to tak, že napríklad pri volaní našej funkcie môžeme zadať nejaký string, číslo alebo boolean, ktorý povie, či sa jedná o pána alebo dámu. A za použitia podmienky sa vykoná buď jeden alebo druhý príkaz. Týmto získame univerzálnu funkciu, ktorá nám vyrieši výpis oslovenia. Šikovné nie? Aby sme sa lepšie rozumeli, poďme si to teda ukázať:
<?php
function vypisOslovenie($jeToPan){
if($jeToPan){
echo "Vazeny pan, ";
}else{
echo "Vazena pani, ";
}
echo "<br>";
echo "<br>";
}
vypisOslovenie(true);
vypisOslovenie(false);
V poslednej ukážke sme si ukázali jednoduché použitie funkcie. V tele programu (mimo deklarácie funkcie) sme ju zavolali dvakrát po sebe, ale v každom prípade s inou hodnotou parametra. Pri dekláracií funkcie očakávame jeden parameter, nazvali sme si ho jeToPan. Táto premenná nám hovorí, či máme alebo nemáme osloviť pána. Podľa podmienky v tele funkcie sa vykoná príslušné oslovenie. Ak by sme pri deklarácii zadali v zátvorkách viacej názvov premenných (argumentov), ale pri jej volaní sme hodnoty nezadali, nič sa nedeje. Môžeme si zadefinovať parametrov koľko chceme, čiže function meno(parameter1, parameter 2, parameter 3...) a takisto môžeme zavolať funkciu s viacerými hodnotami – meno(4, 23, “string“...). Do funkcie prejde len toľko hodnôt, koľko sme pri jej deklarácií zadali argumentov (názvov premenných oddelenných čiarkou). Využívanie parametrov má obrovské možnosti, časom budeme tieto možnosti postupne odhaľovať.