Funkce
Funkce je blok kódu, který lze jednou nadefinovat a pak jej vyvolávat z ostatních částí vaší aplikace. Typicky funkce dostává argument nebo více argumentů, provádí na nich nebo s nimi předdefinovanou sadu operací a vrací výslednou hodnotu. Funkce nám umožňují psát velmi modulární a rozumně strukturované aplikace. Kód, který by se jinak často opakoval, může místo toho existovat na jediném místě a lze jej volat v celém zbytku vašeho programu. Napsáním a otestováním znovupoužitelných funkcí můžete ušetřit čas a snížit počet chyb ve vašem kódu. PHP má mnoho předdeklarovaných funkcí, jako například gettype() nebo isset(). V této kapitole se naučíme vytvářet vlastní, uživatelsky definované funkce.
function název_funkce(argumenty) {
tělo funkce
}
Funkce se deklarují klíčovým slovem function, název funkce smí stejně jako proměnné obsahovat malá a velká písmena, podtržítko a číslice, těmi však nesmí název začínat. PHP zatím v názvu nerozlišuje velikost písmen, takže je jedno, jestli deklarujete a následně voláte funkci mojefunkce(), MojeFunkce() nebo dokonce MoJeFuNkCe(), nicméně doporučuji v tom dodržovat nějaký řád. Například moje_krasna_funkce() nebo MojeKrasnaFunkce() se čte o dost lépe než mojekrasnafunkce(). Za názvem jsou závorky, do kterých se zapisují argumenty (pokud existují) oddělené čárkami. Pokud žádné argumenty nejsou potřeba, ponechají se závorky jednoduše samotné, prázdné. Následují složené závorky, ve kterých je zapsáno tělo funkce. Pro vyvolání funkce prostě napíšeme její název následovaný párem závorek s argumenty. Kdysi dávno, v PHP verze 3, musela být uvedena deklarace funkce před jejím voláním, v PHP 4 i 5 může být funkce volána ještě před její deklarací.
<?php
// Deklarace a definice funkce:
function TretiMocnina($Cislo) {
$Vysledek = $Cislo * $Cislo * $Cislo;
return $Vysledek;
}
// Volání funkce TretiMocnina():
echo TretiMocnina(5); // Vypíše: 125
?>
Příkazem echo jsme zavolali funkci TretiMocnina() a předali jí argument (5). Funkce toto číslo umocnila a výsledek pomocí příkazu return vrátila, echo tedy vypíše 125.
Funkce nemusí nutně vracet hodnotu. Níže uvedená funkce nepoužívá příkaz return:
<?php
function Alert($Zprava) {
echo '<script language="javascript" type="text/javascript">', "\r\n";
echo '<!--', "\r\n";
echo 'window.alert("'.$Zprava.'");', "\r\n";
echo '-->', "\r\n";
echo '</script>', "\r\n";
}
Alert('Heslo, které jste zadali, není platné!');
?>
Příkaz return bez uvedení návratové hodnoty se dá také použít pro ukončení provádění funkce. Níže uvedená funkce Alert() byla upravena tak, aby se zastavila v případě, že by $Zprava obsahovala prázdný řetězec.
<?php
function Alert($Zprava) {
if ($Zprava == '') {
return;
}
echo '<script language="javascript" type="text/javascript">', "\r\n";
echo '<!--', "\r\n";
echo 'window.alert("'.$Zprava.'");', "\r\n";
echo '-->', "\r\n";
echo '</script>', "\r\n";
}
Alert('Heslo, které jste zadali, není platné!');
Alert(''); // Toto volání nevygeneruje kód JavaScriptu.
?>
Předávání argumentů
Argumenty umožňují předat funkci vstupní hodnoty. Když napíšeme TretiMocnina(3), "3" je argument. Argument je ve funkci dostupný jako parametr $Cislo. Parametr převezme hodnotu odpovídající argumentu, který je předán při volání funkce. Funkce TretiMocnina() potom používá tuto hodnotu pro výpočet návratové hodnoty.
Například funkce NovyRadek() v příkladu níže převezme argument (5), který určuje, kolik nových řádků se má vypsat. Uvnitř funkce počet řádků, které se mají vložit, prezentuje parametr $x (v tomto příkladu 5).
<?php
function NovyRadek($x) {
// Vypíše $x-krát <br>
for ($i = 0; $i < $x; $i++) {
echo '<br>', "\r\n";
}
}
echo 'začátek';
NovyRadek(5);
echo 'konec';
?>
Implicitně jsou argumenty předávány hodnotou. To znamená, že proměnná parametru uvnitř funkce pracuje s kopií hodnoty, která je jí předána. Pokud se změní hodnota parametru, nezmění se hodnota proměnné, která jí byla předána při volání.
<?php
function Polovina($a) {
$a = $a / 2;
echo $a;
}
$a = 20;
echo $a; // Vypíše: 20
Polovina($a); // Vypíše: 10
echo $a; // Vypíše zase 20
?>
Poté, co byla předána funkci Polovina(), se hodnota $a nezměnila, jelikož byla funkci předána hodnota. Na rozdíl od toho se, pokud je parametr předán odkazem, změny projeví změnou v proměnné, která je funkci předána při volání. Znak & (ampersand) umístěný před název parametru určuje, že má být tento parametr předán odkazem.
<?php
function Zvyseni(&$Plat, $Procent) {
// Zvýšení obsahu proměnné $Plat o počet procent uvedený v argumentu $Procent
$Plat += $Plat * $Procent / 100;
}
$x = 10000;
echo 'Plat před zvýšením: ', $x, '<br>', "\r\n"; // Vypíše: 10000
Zvyseni($x, 25);
echo 'Plat po zvýšení: ', $x, '<br>', "\r\n"; // Vypíše: 12500
?>
Také je možné stanovit výchozí hodnotu parametru, čímž se parametr stane nepovinným. To se provádí přiřazením hodnoty parametru v deklaraci funkce.
<?php
function NovyRadek($x = 1) {
// Vypíše $x-krát <br>
for ($i = 0; $i < $x; $i++) {
echo '<br>', "\r\n";
}
}
echo 'text 1';
NovyRadek(); // Vloží <br> jednou.
echo 'text 2';
NovyRadek(2); // Vloží <br> dvakrát.
?>
Rozsah platnosti proměnné
Uvažujte nad následujícím příkladem:
<?php
$Pozice = 'm';
function ZmenaPozice() {
$Pozice = 'e';
}
ZmenaPozice(); // Změníme hodnotu proměnné $Pozice
echo $Pozice; // Vypíše: m
?>
Jakto, že funkce nezměnila hodnotu proměnné? Proměnné použité uvnitř funkcí jsou lokální, a proto jsou odlišné od proměnných deklarovaných mimo funkci, které jsou globální. Globální proměnné jsou dostupné kdekoliv ve skriptu, ale ve funkcích ne. Pro přístup ke globální proměnné uvnitř funkce se musí použít příkaz global. Tento příkaz PHP říká, že nevytváříme novou proměnnou, ale chceme použít proměnnou, která je dostupná jinde ve skriptu.
<?php
$Pozice = 'm';
function ZmenaPozice() {
global $Pozice;
$Pozice = 'e';
}
ZmenaPozice();
echo $Pozice; // Vypíše: e
?>
Nyní náš kód vypíše "e", protože používáme ve funkci i mimo funkci tu samou proměnnou $Pozice.
Doba existence proměnné
Kromě rozsahu platnosti proměnné musíme uvažovat i nad dobou existence proměnné. Může nastat situace, kdy bychom chtěli, aby si proměnná mezi jednotlivými voláními funkce uchovala svou hodnotu. V následujícím kódu je lokální proměnná $Pocitadlo vytvořena a vynulována při každém volání funkce.
<?php
function Pocitadlo() {
$Pocitadlo = 0;
$Pocitadlo++;
}
?>
To v tomto kontextu užitečné není. Potřebujeme udělat z proměnné $Pocitadlo statickou proměnnou. Statické proměnné si uchovají předchozí hodnotu mezi jednotlivými voláními funkce.
<?php
function Pocitadlo() {
static $Pocitadlo = 0;
$Pocitadlo++;
}
?>
Když deklarujeme proměnnou pomocí static, říkáme tím PHP, že chceme, aby její hodnota zůstala mezi jednotlivými voláními funkce zachována. Při úplně prvním volání funkce bude statická proměnná vytvořena a bude jí přiřazena hodnota (v tomto případě 0), ale při příštím volání si mezi jednotlivými voláními funkce zachová svou hodnotu. Proměnná nebude znovu inicializována. Tato hodnota bude ale zachována pouze po dobu provádění skriptu. Pokud uživatel stránku načte znovu, proměnná bude znovu inicializována při prvním volání v provádění skriptu.
Vnořené funkce
Funkce mohou být vnořeny do sebe, ačkoliv pro to není, kromě organizačního, žádný důvod. Možná budete chtít, aby funkce obsahovala jinou funkci, na které závisí. Všechny funkce, včetně vnořených, jsou globální. To znamená, že všechny funkce mohou být volány z jiného kódu ve skriptu. Zde je příklad vnořených funkcí:
<?php
function Objem($r) {
// Vrací objem koule s poloměrem $r
function TreTiMocnina($Cislo) {
// Vrací třetí mocninu parametru $Cislo
return $Cislo * $Cislo * $Cislo;
}
return 3.14 * TretiMocnina($r);
}
$Polomer = 2;
echo Objem($Polomer); // Vypíše: 25.12
echo TretiMocnina(4) // Vypíše: 64
?>
I když je funkce TretiMocnina() vnořena do funkce Objem(), můžeme ji volat z hlavního skriptu. Proto bychom mohli tento kód napsat jednodušeji (a čitelněji) takto:
<?php
function TreTiMocnina($Cislo) {
// Vrací třetí mocninu parametru $Cislo
return $Cislo * $Cislo * $Cislo;
}
function Objem($r) {
// Vrací objem koule s poloměrem $r
return 3.14 * TretiMocnina($r);
}
$Polomer = 2;
echo Objem($Polomer); // Vypíše: 25.12
echo TretiMocnina(4) // Vypíše: 64
?>
Ve skutečnosti je hodnota pi vestavěnou konstantou PHP s názvem M_PI, takže bychom mohli funkci Objem() definovat takto:
<?php
function Objem($r) {
// Vrací objem koule s poloměrem $r
return M_PI * TretiMocnina($r);
}
?>
Rekurze
Rekurze je případ, kdy funkce volá sebe sama. Tato zacyklená definice může vést k elegantním algoritmům. Problém je rozdělen na menší úlohy a ty jsou několikrát opakovány. Rekurze je v matematice běžná a jedním příkladem může být exponenciál:
<?php
function Mocnina($Zaklad, $Exp) { // řádek 1
if ($Exp) { // řádek 2
return $Zaklad * Mocnina($Zaklad, $Exp - 1); // řádek 3
} // řádek 4
return 1; // řádek 5
}
?>
Tato funkce je založená na tom, že xy je ekvivalentem x * x(y - 1)
Problém "čtyři na třetí" jsme rozdělili do dvou jednodušších problémů: "čtyři krát (čtyři na druhou)". A "čtyři na druhou" může být rozděleno na "čtyři krát (čtyři na první)". I když je tento proces náročnější na pochopení, je to elegantní řešení (často je ale efektivnější, z důvodu rychlosti zpracování, místo rekurze použít cyklus).
Zavolejme funkci a podívejme se, co dělá.
<?php
echo Mocnina(4, 3);
?>
- Funkce Mocnina() je spuštěna. $Zaklad je nastaven na 4 a $Exp je nastaven na 3.
- Na řádku 2 je testována hodnota $Exp. Jelikož není nula, řádek 3 se provede.
- Řádek 3 zavolá druhou invokaci funkce Mocnina() a předá jí argumenty 4 a 2.
- Na řádku druhé invokace funkce Mocnina() $Exp stále není nula, takže se provede řádek 3.
- Řádek 3 vyvolá třetí invokaci funkce Mocnina() a předá jí argumenty 4 a 1.
- Na řádku 2 třetí invokace funkce Mocnina() $Exp stále není nula (je 1), takže se řádek 3 provede.
- Řádek 3 vyvolá čtvrtou invokaci funkce Mocnina() a předá jí argumenty 4 a 0.
- Jelikož je $Exp 0, řádek 3 se neprovede. Pokračuje se na řádku 5 a funkce vrátí hodnotu 1. Tato hodnota je předána zpět řádku 3 třetí invokace funkce Mocnina() a čtvrtá invokace je ukončena.
- Hodnota 1 je nyní dosazena místo funkce Mocnina() na řádku 3. Ta je poté násobena proměnnou $Zaklad, což je 4. Třetí invokace skončí a vrátí tuto hodnotu 4 řádku 3 druhé invokace.
- Řádek 3 druhé invokace funkce násobí hodnotu 4 proměnnou $Zaklad a vrátí tuto hodnotu (16) řádku 3 první invokace funkce.
- Řádek 3 první invokace funkce násobí hodnotu 16 proměnnou $Zaklad a vrátí novou hodnotu (64).
Tato funkce pracuje pouze s celými kladnými hodnotami pro $Exp. Záporné nebo zlomkové exponenty způsobí nekonečnou smyčku. Víte, proč?
Přiřazování funkcí proměnným
PHP umožňuje, aby proměnné obsahovaly odkaz na funkci. To může být užitečné, když budou dynamické podmínky určovat, která funkce by měla být volána za dané situace. Když proměnná obsahuje název funkce, může být funkce volána umístěním závorek s argumenty (pokud nějaké jsou) za název proměnné.
<?php
switch ($Cas) {
case 8:
$NacistFunkci = 'Vstavat';
break;
case 12:
$NacistFunkci = 'Obedvat';
break;
case 22:
$NacistFunkci = 'Spat';
break;
}
$NacistFunkci(); // Zavolá vhodnou funkci s ohledem na $Cas
?>