(hlavička webu)

Funkce

Už v kapitole o [odkaz]základech syntaxe[/odkaz] jsme si řekli o funkcích, argumentech (resp. parametrech) a jak zavolat vestavěnou funkci PHP. Později jsme se seznámili i s dalšími funkcemi, ale stále šlo o vestavěné funkce PHP. V této kapitole si ukážeme, jak vytvářet své vlastní funkce.

Poznámka: Funkce se týkají zejména procedurálního programování v PHP. Pokud chcete raději programovat objektově, místo funkcí budete vytvářet třídy a metody. Z této a následujících kapitol ale budete potřebovat jednu důležitou znalost, a sice kontext, který se uplatní i v objektově-orientovaném programování.

Zápis funkce

Funkce se zapisuje klíčovým slovem function, následovaným závorkami, ve kterých mohou být definovány argumenty, a kódem funkce ve složených závorkách. Příklad:
function pozdrav() {
  echo "Ahoj!";
}
Volání funkce pak vypadá stejně jako u vestavěných funkcí, tedy např.:
pozdrav();
Poznámka: V názvech funkcí se, stejně jako u proměnných, doporučuje používat jen písmena bez diakritiky, čísla, pomlčku a podtržítko. PHP dovoluje i některé další znaky, ale je lepší si vystačit jen s těmi uvedenými, například některá vývojová prostředí mohou s jinými znaky v názvu mít problémy. Velikost písmen se u funkcí nerozlišuje, takže u funkce pozdrav() definované výše budou fungovat i volání Pozdrav(); PozdraV() či POZDRAV(). Že to funguje ale ještě neznamená, že je to dobrý nápad. Kvůli přehlednosti byste vždy měli používat jen jednu formu zápisu, čili volání stejné jako definici.

Argumenty

Funkce také může mít argumenty a může vracet hodnotu. Hodnota se vrací pomocí klíčového slova return a argumenty se píší do závorek za název funkce. Příklad:
function sude($cislo) {
  // zkontroluje, zda je číslo sudé
  // Číslo je sudé, pokud číslo modulo 2 je 0
  return (($cislo % 2) == 0) ? true : false;
}
Poznámka: Výsledkem samotného (($cislo % 2) == 0) je true nebo false, takže zápis by mohl být ještě kratší: return (($cislo % 2) == 0). Zápis s podmíněným operátorem byl použit jen proto, aby bylo na první pohled zřejmé, co funkce vrací.

Volání funkce by pak vypadalo třeba sude(5); a jeho výsledkem bude hodnota, kterou vrací funkce. Celý kód by tedy mohl vypadat třeba takto:

<?php
  // vložení hlavičky stránky, kterou jsme vytvořili ve [odkaz]4. kapitole[/odkaz]
  include "spolecna_hlavicka.php";

function sude($cislo) { // zkontroluje, zda je číslo sudé return (($cislo % 2) == 0) ? true : false; } if (isset($_GET["cislo"])) { // Konverze na číslo, zároveň případné nežádoucí vstupy změní na 0 $vstup = intval($_GET["cislo"]); $vyrok = "není";

if (sude($vstup)) { $vyrok = "je"; } echo "Číslo $cislo $vyrok sudé"; } // níže HTML formulář pro odeslání ?> <form action="" method="get"> <label for="cislo">Zadejte číslo:</label> <input type="text" name="cislo" id="cislo"> <input type="submit" name="odeslat" value="Odeslat"> </form>

Funkce může mít argumentů i více, pak se oddělují čárkami. Také lze argumentům zadat výchozí hodnoty. Argumenty se zadanou výchozí hodnotou by měly být v seznamu argumentů funkce na konci (jinak to nemá smysl) a stávají se nepovinnými. Argumenty bez výchozí hodnoty jsou povinné a při volání funkce je nelze vynechat. To si můžete vyzkoušet, když funkci sude z příkladu výše zkusíte zavolat bez argumentu: sude(); Výsledkem bude varování „Missing argument 1 for sude()“. Výchozí hodnota u nepovinných argumentů se zadává takto:
function funkce($prvni, $druhy=0, $treti=1) { …
Příklady volání takové funkce:
funkce(1, 2, 3); // hodnoty argumentů jsou 1, 2, 3
funkce(1, 2); // hodnoty argumentů jsou 1, 2, 1
funkce(1); // hodnoty argumentů jsou 1, 0, 1
funkce(); // skončí chybou, první argument musí být uveden

Předání argumentu referencí

Když se funkci předá proměnná jak jsme to dělali výše, zkopíruje se do funkce jen její hodnota a pracuje se s ní nezávisle na původní proměnné. Proto například toto nefunguje dle očekávání:
<?php
  function dvakrat($hodnota) {
    $hodnota = $hodnota * 2;
  }

$cislo = 5; dvakrat($cislo); echo $cislo; // vypíše 5 a ne 10 ?>

Protože uvnitř funkce se pracuje jen s kopií hodnoty, případné změny se neprojeví vně funkce. Toho můžeme docílit tak, že do funkce předáme tzv. referenci na proměnnou. Reference se označuje při definici funkci uvedením ampersandu (&) před daný argument. Když se pak funkci předá nějaká proměnná, předá se jí odkaz přímo na tu proměnnou a změny její hodnoty uvnitř funkce se projeví i vně funkce. Upravený příklad tedy již bude fungovat dle očekávání:
<?php
  function dvakrat(&$hodnota) {
    $hodnota = $hodnota * 2;
  }

$cislo = 5; dvakrat($cislo); echo $cislo; // vypíše 10 ?>

Reference se občas hodí, ale neměli byste je používat místo návratové hodnoty (což dělá i příklad výše). Použití návratové hodnoty bývá přehlednější. Příklad výše by tedy šlo upravit takto:
<?php
  function dvakrat($hodnota) {
    return $hodnota * 2;
  }

$cislo = 5; $cislo = dvakrat($cislo); echo $cislo; // vypíše 10 ?>

[h2#n5]Rekurze[/preh2] Funkce může volat i sama sebe (tzv. rekurze). Není to ale příliš časté a patří to mezi pokročilejší techniky programování. Stejně jako u cyklů i u rekurze je třeba dát pozor, aby řetěz volání někdy skončil a nenastal nekonečný cyklus. Klasickým příkladem využití rekurze je výpočet faktoriálu čísla:
function faktorial($cislo) {
  if ($cislo < 0) return 0; // chyba

if($cislo < 2) return 1; // 0! a 1! = 1 else { // Jinak je výsledek číslo krát faktoriál o 1 nižšího čísla return $cislo * faktorial($cislo - 1); } }

Rekurze je ovšem oproti jiným technikám náročnější na systémové zdroje, zejména při větším počtu vnoření, takže bývá často výhodnější rekurzivní volání funkce nahradit cyklem. To lze udělat i v případě faktoriálu:
function faktorial($cislo) {
  if ($cislo < 0) return 0; // chyba

$vysledek = 1; for($i = 2; $i <= $cislo ; $i++) { $vysledek = $vysledek * $i; } return $vysledek; }

Návrh funkcí

Několik užitečných rad, jakým způsobem organizovat kód do funkcí:
(patička webu)