Lekce 6: Funkce
- Funkce je jakousi zkratkou pro větší počet procesů, pokud je nechceme vypisovat celé.
- Proto doporučuji využívat funkce, aby v kódu nedocházelo ke zbytečné duplicitě.
- Přeci jenom upravovat jeden údaj 10x je dost šílené. Proto existují funkce, ve kterých si napíšeme krátkej script a tu funkci poté v kódu používáme.
Takže pokud nastane nějaká změna, tak se upraví pouze hlavní funkce.
- V PHP již existuje celá řada předpřipravených funkcí, které můžete použít. S některými jsme se už setkali s jinými teprve setkáme.
První funkce
- Vytváření vlastních funkcí je jednoduché. Na rozdíl od jiných jazyků jako třeba Java nebo C / C++ si PHP automaticky zjištujě o jaký typ se jedná.
Takže se nemusíme starat, jestli výsledná hodnota bude číslo nebo znak a podle toho deklarovat funkci.
- Takže si ukážem příklad, jak přes funkci vypsat nějaký text.
function mojeFunkce() // deklarace nove funkce s nazvem "mojeFunkce"
{
echo "Ahoj světe"; // v bloku funkce je logika, ktera se ma udelat
}
mojeFunkce(); // zavolame funkci -> vypise text "Ahoj světe"
- Jak je vidět, tak za názvem funkce jsou závorky
(). Ty slouží pro parametry funkce, tady žádný parametr není, proto prázdné závorky.
- Tato funkce je typu
void. Což znamená, že nevrací žádnou hodnotu.
function mojeFunkce()
{
return "Ahoj světe"; // funkce hodnotu nevypise ale pouze vrati
}
mojeFunkce(); // nevypise nic, protoze funkce vraci nejakou hodnotu
echo mojeFunkce(); // zde uz vypiseme obsah funkce
$text = mojeFunkce(); // priradime hodnotu ve funkci promenne $text
echo $text; // vypiseme "Ahoj světe"
- Zde je krásně vidět, že stačí zaměnit
echo za
return a hned se funkce chová jinak.
- Klíčové slovo
return automaticky mění typ funkce z
void na
string, protože vrací text (v tomhle případě).
- Jak je vidět, tak pokud funkce vrací nějakou hodnotu, tak hodnotu co funkce vrací lze přířadit jakékoliv proměnné stejného typu.
function sectiCisla($a, $b) // funkce s 2 parametry
{
return $a + $b; // secte 2 parametry (pravdepodobne cisla)
}
echo "Součet je: ".sectiCisla(5, 2); // vypise -> Součet je: 7
- Zde je funkce, která má 2 parametry. Parametry se zapisují mezi závorky za název funkce a oddělují se čárkou.
- Pokud by jsme místo čísel dosadili cokoliv jiného, třeba znak nebo slovo, tak to bere jako 0.
Pozor: Hodnoty
true a
false jsou podstatě čísla 1 a 0!
Doplněk: Nikdy prosím netvořte funkci ve funkci. Sice je to možné, ale nedělá se to! Hlavně k tomu funkce nejsou určený a v takovým případě je použitelnost limitovaná.
function hlavniFunkce() // hlavni funkce
{
function vedlejsi() // prvni pod-funkce
{
echo "Vedlejší text";
}
}
hlavniFunkce().vedlejsi(); // volani vedlejsi funkce
- Přesně o tom mluvim. Tohle
nikdy nedělat!
- Sice to funguje, ale hlavni funkci lze zavolat pouze jednou. To znamená, že to je nevyužitelný.
Pokud bych znova zavolal
hlavniFunkce().vedlejsi();, tak mi to napíše
fatal error!
Přístup
- Určitě jste si všimli, že nešlo přistupovat z funkce k proměnným mimo funkci. Je to způsobeno tím, že veškeré proměnné uvnitř funkce jsou lokální.
To znamená, že pokud skončí funkce, tak zaniknou i všechny lokalní proměnné uvnitř funkce.
- Ale nebojte, jsou tu 3 možnosti, jak přistupovat k proměnným mimo funkci.
- Možnost první - pomocí klíčového slova global.
$cislo = 10;
function vypisCislo()
{
global $cislo; // nastavi pristup k promenne $cislo, ktera je mimo funkci
echo $cislo; // vypise cislo
}
vypisCislo(); // vypise cislo 10
- Možnost druhá - pomocí
$GLOBALS.
$cislo = 10;
function vypisCislo()
{
echo $GLOBALS['cislo']; // umozni pristup k promenne $cislo a vypise ji
}
vypisCislo(); // vypise cislo 10
- Možnost třetí - pomocí
parametru funkce.
- Tuto možnost doporučuji používat pokud je to možné.
$cislo = 10;
function vypisCislo($num) // nastavime funkci se vstupnim parametrem
{
echo $num; // vypise hodnotu z parametru funkce
}
vypisCislo($cislo); // vypise cislo 10
- Tak, a k funkcím by to bylo asi vše, jen bych ještě dodal, že stejně jako jazyk Java nebo C#, který mohou k parametru ve funkci přímo přidělit hodnotu,
tak i PHP toto umožňuje.
- Tímto se dá vyhnout určitým problémům.
$cislo = 10; // hodnota
// prvni funkce s parametrem, ktery ma vychozi hodnotu 0
function vypis_1($num = 0) // lze priradit i null, pote se nevypise nic
{
echo $num;
}
// druha funkce s parametrem, ktery nema vychozi hodnotu
function vypis_2($num)
{
echo $num;
}
vypis_1($cislo); // vypise cislo 10
vypis_1(); // vypise cislo 0
vypis_2($cislo); // vypise cislo 10
vypis_2(); // chyba - funkce ocekava nejakou hodnotu!
Rekurzivni funkce
- Rekurzivní funkce je taková funkce, který volá sama sebe.
function cyklus($cislo = 0) // funkce s jednim parametrem, pro zadani cisla
{
if ($cislo > 1000) return; // ukonci funkci, pokud hodnota parametru bude vetsi jak 1000
echo $cislo.", "; // vypisuje hodnoty
cyklus($cislo * 2); // vola sama sebe a zvysi parametr o dojnasobek
}
cyklus(100); // vypise 100, 200, 400, 800
- Jak vidite, tak lze pouzit funkci i jako cyklus, jen má 2 nevýhody. Za prvé je tu limit volání.
Výchozí nastavení je, že funkce sama sebe může zavolat
maximálně 100x. Druhá nevýhoda je, že zde musí být
vždy podmínka, která ukončí funkci.
- Používání rekurzivní funkce patří mezi pokročilejší techniky. Někde se však bez takové funkce neobejdem a kolikrát rapidně zkrátí kód.
- Doufám, že vám tato lekce o funkcích nějak pomohla :)
Reference
- Pro hodně lidí to je něco, co v životě neviděli a ani se s tím nejspíš nesetkali.
- Refenrece je vlastně odkaz na zdroj. Rozdíl je v tom, že při volání funkce se proměnná vytváří a bere si informace z funkce.
- Referenci vytvoříme tak, že před proměnnou dámé znak ampersandu &.
- Pojďmě si tedy ukázat jednoduchý příklad.
function vypis($text, &$znaku = null)
{
$znaku = strlen($text); // zjisti pocet znaku slova
echo $text; // vypise text
}
vypis("ahoj"); // vypise slovo "ahoj"
vypis("ahoj", $pocet); // vypise tez slovo "ahoj" a vytvori promennou $pocet
echo $pocet; // vypise 4 (pocet znaku slova "ahoj")
- Další příklad ukazuje, jak funkce má pouze reference a to 2.
$slovo = "ahoj";
$cislo = 10;
$delitel = 2;
function ref(&$length = null, &$sum = null)
{
global $slovo, $cislo, $delitel; // umozni pristupovat k promennym mimo funkci
$length = strlen($slovo); // zjisti delku slova
$sum = $cislo / $delitel; // zjisti vysledek po deleni
}
ref($delka, $celkem); // deklarace promennych + pridani hodnot
echo $delka; // vypise delku slova "ahoj" = 4
echo $celkem; // vypise vysledek po deleni = 5
Dobrovolný domácí úkol
1) Vytvořte funkci, která zjistí, jestli vstupní parametr (číslo) je prvočíslo nebo ne. A cyklus do 100, který vypíše pomocí funkce všechna prvočísla.
// funkce pro zjisteni, zda se jedna o prvocislo nebo ne
function prime($num = 0)
{
if ($num < 2 || $num % 2 == 0 && $num != 2) return false;
for ($i = round(sqrt($num)); $i > 1; $i--)
{
if ($num % $i == 0) return false;
}
return true;
}
// cyklus do 100, ktery vypisuje pouze prvocisla
for ($i = 0; $i <= 100; $i++)
{
if (prime($i)) echo $i.", ";
}
2) Vytvořte rekurzivní funkci, která vypíše faktoriál ze zadaného čísla.
function faktorial($num = 0)
{
if ($num == 0) return 1; // pokud $num bude 0, tak ukonci funkci
// kazde volani funkce snizi puvodni parametr o 1 a znovu se zavola
// takze hodnoty budou pri zadani cisla 5: 5*4 .. 4*3 .. 3*2 .. 2*1 => 5*4*3*2*1 = 120
return $num * faktorial($num - 1);
}
echo faktorial(6);
3) Vytvoř si mimo funkci nějaké prázdné pole. Dále vytvoř 2 funkce,
kde první funkce bude obsahovat 3 parametry (počet prvků, min. číslo, max. číslo) a bude sloužit pro naplnění pole. Návratový typ bude array a pole naplní 10 čísly v rozsahu čísel 1-9.
A druhá funkce bude mít jeden parametr typu array a vypíše pole.
$pole = array(); // deklaruje prazdne pole
// prvni funkce, ktera naplni pole nahodnymi prvky
function naplnPole($prvku = 0, $min = 0, $max = 9)
{
$pole = array(); // lokalni prazdne pole
for ($i = 0; $i < $prvku; $i++)
{
$pole[] = rand($min, $max); // naplni pole
}
return $pole; // vrati naplnene pole
}
// druha funkce pro vypis pole
function vypisPole($pole = array())
{
// vypise vstupni pole
for ($i = 0; $i < count($pole); $i++) echo $pole[$i].", ";
}
$pole = naplnPole(10, 1, 5); // do pole se priradi naplnene pole
vypisPole($pole); // vypise se pole