Lekcje >> Podstawy PHP
Polimax

Drukarnia w Warszawie realizująca druk wizytówek, plakatów jak również fotoksiążki, fotoobrazy i fotokalendarze - z wysyłką na terenie całego kraju.

Budowa i zastosowanie funkcji w PHP

Funkcje wbudowane, prototyp funkcji

Do tej pory mamy pewne wyobrażenie funkcji - jako kodu, który wykonuje określone zadanie i który możemy stosować wielokrotnie, przy czym nie musimy przepisywać bloku instrukcji składających się na funkcję - wystarczy podać nazwę funkcji. Ponieważ zaczniemy stosować funkcje wbudowane musimy poznać formalny sposób przedstawiania funkcji. Padło nowe pojęcie funkcji wbudowanej - jest to funkcja, która została zdefiniowana przez twórców danego środowiska programistycznego. Tak więc są to funkcje gotowe, które możemy od razu zastosować w kodzie. Możemy także samodzielnie definiować (tworzyć) własne funkcje.

Opisując funkcję, przedstawia się jej prototyp. Prototyp pokazuje argumenty funkcji oraz zwracany wynik. Omówmy dla przykładu funkcję wudowaną string gettype(mixed $arg). Oto jej poszczególne elementy:

  • string - typ zwracanego wyniku. Typy zmiennych już znasz. Ale co to znaczy zwracany wynik? Po prostu w wyniku wykonania funkcji, powstaje jakaś wartość określonego typu. Omawiana funkcja zwraca wartość typu string. Należy także wyjaśnić, że w przypadku tej funkcji, zwracaną wartością, jest nazwa typu argumentu $arg. Przyjrzyjmy się zastosowaniu tej funkcji w kodzie:
    <?php
      $a=3;
      $b=gettype($a);
      echo $b;
    ?>
    
    Jak myślisz, co wypisze funkcja wbudowana echo? Tak przy okazji, echo jest elementem składni PHP, dlatego nie stosujemy nawiasów, które są obowiązkowe we wszystkich funkcjach. Zwróć uwagę, że zmiennej $b przypisaliśmy wynik zwrócony przez funkcję gettype($a). Tym samym zainicjowaliśmy zmienną $b, która jest tego samego typu, co typ zwracanego wyniku, a więc typu string. Tym wynikiem jest nazwa typu a więc w tym przypadku przeglądarka pokaże napis integer.
  • Jeżeli funkcja nie zwraca określonej wartości (ale coś wykonuje), wtedy zamiast nazwy typu jest napisane void.
  • gettype oznacza nazwę funkcji. Po nazwie znajdują się obowiązkowo nawiasy okrągłe, w których wymienione są po przecinkach argumenty funkcji.
  • Argument funkcji, to zmienna, która jest przetwarzana wewnątrz funkcji po to, aby funkcja mogła cos wykonać i(lub) zwrócić wynik. Najczęściej zmiany wartości zmiennej wewnątrz funkcji, nie mają wpływu na wartość tej zmiennej (tzw. przekazywanie przez wartość). Argumenty wymieniamy po przecinkach, pisząc przed każdym z nich nazwę typu. W naszym przykładzie, mamy tylko jeden argument mixed $arg. A gdzie jest tutaj typ zmiennej? Nie mamy akurat typu, ale pseudotyp mixed, który wskazuje, że można zastosować dowolny tyb argumentu $arg.
  • Funkcja może posiadać argumenty opcjonalne, tzn. takie, które mogą być, ale nie muszą. W prototypie funkcji, takie agumenty pokazywane są w nawiasach kwadratowych.

Ćwiczenie 1_9_0_1. Sprawdzanie działania funkcji wbudowanej gettype()

Zastosuj pokazany wcześniej kod w pojedynczym pliku *.php.

Przeglądarka wyświetliła napis integer, ponieważ taki jest typ zmiennej $a, co zostało sprawdzone za pomocą funkcji wbudowanej gettype().

Tworzenie własnych funkcji

Nawet w prostych skryptach, bardzo często istnieje potrzeba, zdefiniowania własnej funkcji. Dzięki temu, otrzymujemy kod prostszy w zapisie i bardziej czytelny. Pierwszym etapem jest definiowanie funkcji. Raz zdefiniowaną funkcję możemy potem wielokrotnie wywoływać (stosować) w kodzie skryptu.

Definicja funkcji

Definiowanie funkcji, to nic innego jak napisanie kodu, który coś nam obliczy, lub(i) coś nam wykona. Musimy utworzyć następującą konstrukcję:

function nazwa_funkcji($arg1, $arg2, $arg3, &$arg4, &$arg5, &$arg6)
{
  instrukcja_1;
  instrukcja_2;
  instrukcja_3;
  return $wynik;
  instrukcja_4;
}

Uwagi:

  • Najpierw występuje słowo kluczowe function.
  • Kolejnym elementem jest nazwa funkcji podlegająca następującym zasadom:
    • Powinna być sensowna - oddawać to co wykonuje funkcja. Najlepiej oddaje to zasada - krótko, zwięźle i na temat.
    • Można stosować litery alfabetu łacińskiego (bez "polskich ogonków") oraz cyfry, przy czym cyfra nie może być pierwszym znakiem nazwy.
    • Można stosować znak podkreślnika (zamiast spacji) np. moja_funkcja.
    • W nazwie można stosować duże i małe litery, przy czym interpreter - inaczej jak podczas analizowania nazwy zmiennej - nie rozróżnia wielkości liter. Tak więc Moja_Funkcja i moja_funkcja, jest identyfikowane identycznie. Przyjęte jest jednak stosowanie małych liter i tę zasadę będziemy konsekwentnie stosować.
    • Nazwa powinna być unikatowa, biorąc pod uwagę również nazwy funkcji wbudowanych.
  • W nawiasach okrągłych wymienia się argumenty, oddzielając je przecinkami. Dla przykładu pokazano kilka argumentów. Jeżeli przed nazwą zmiennej występuje tylko znak dolara, to mamy tzw. przekazywanie przez wartość. Wewnątrz funkcji tworzona jest wtedy kopia danej zmiennej i wszystkie działania wykonywane są na tej kopii. Dlatego wszelkie zmiany wartości danej zmiennej dotyczą jedynie jej kopii. Po wykonaniu funkcji wartość zmiennej pozostaje niezmieniona. Jeżeli jednak przed znakiem dolara znajduje się & (ampersand), to mamy przekazywanie przez referencję. W takiej sytuacji, zmiana wartości zmiennej wewnątrz funkcji, będzie obowiązywać po zakończeniu funkcji.
  • Instrukcje tworzące blok(ciało, treść) funkcji objęte są nawiasami klamrowymi. W tym bloku mogą występować oczywiście inne bloki obejmowane nawiasami klamrowymi.
  • Zmienne inicjowane wewnątrz funkcji są niszczone z chwilą kończenia funkcji.
  • Jeżeli użyjemy słowa kluczowego return, to funkcja zwróci wartość, znajdującą się po prawej stronie tego słowa, przy czym może tam się znajdować konkretna wartość np. 7.35, zmienna przechowująca wartość np. $a, jak również wyrażenie, które jak wiemy również zwraca jakąś wartość. Bardzo ważne jest to, że zastosowanie return automatycznie kończy funkcję, tak więc w pokazanym wzorze, instrukcja_4; nie zostanie wykonana.
  • Funkcja nie musi posiadać argumentów, wtedy piszemy same nazwiasy ().

Definicję funkcji możemy umieścić w kilku miejscach:

  • Na początku dokumentu (np. sekcji body), tak aby nie "zaciemniać" kodu HTML:
    <?php
      function moja_funkcja()//definicja funkcji
      {
        ...
      }
    ?>
    
    Kod PHP, w którym zastosujemy funkcję, może znajdować się w w dalszym miejscu dokumentu:
    <?php
      ...
      moja_funkcja();//wywołanie funkcji
      ...
    ?>
    
  • Na początku skryptu - ten sposób będziemy stosować najczęściej tworząc proste skrypty:
    <?php
      function moja_funkcja()//definicja funkcji
      {
        ...
      }
      
      instrukja_1;
      ...
      moja_funkcja();//wywołanie funkcji
      ...
    ?>
    
  • W zewnętrznych plikach, co przy większych projektach jest niezbędne. Dołączanie takich zewnętrznych kodów, odbywa się za pomocą funkcji wbudowanych require() oraz include(). W dalszym toku nauki, nauczymy się stosować tę metodę.

Wywołanie funkcji

Przykłady zostały już pokazane. Raz zdefiniowaną funkcję możemy wielokrotnie wywoływać w różnych miejscach skrypu, lub nawet skryptów - jeżeli definicje znajdują się w zewnętrznych plikach. Postać jest bardzo prosta - piszemy nazwę funkcji, natomiast jako argumenty podajemy bieżące zmienne. Musimy przy tym pamiętać o zachowaniu zgodności typów.

Ćwiczenie 1_9_0_2. Definiowanie i wywoływanie funkcji. Przekazywanie przez wartość i referencję

Zastosuj pokazany poniżej kod w pojedynczym pliku *.php.

<?php
  /*definicja funkcji. Funkcja pokaże
  przekazywanie przez wartość
  i przez referencję*/
  function referencja($a, &$b)
  {
    $a+=10;
    $b+=$a;
    /*Zmienne $a i $b zmieniły wartość,
    jednak po zakończeniu funkcji, 
    będzie to zachowane tylko w przypadku
    $b - przekazywanie przez referencję*/
  }

  /*definicja drugiej funkcji. Funkcja iloraz
  jak nazwa wskazuje dzieli $a przez $b*/
  function iloraz($a, $b, &$wykonalne)
  {
    $wykonalne=($b!==0);//$b musi być różne od zera
    if (!$wykonalne) return; //przerywamy funkcję
    return $a/$b;
  }
  
  //Zaczynamy skrypt
  $x=2;
  $y=3;
  referencja($x, $y);
  echo $x.'<br />';//wartość niezmieniona
  echo $y.'<br />';//wartość zmieniona
  
  $wynik=iloraz($x, $y, $ok);//wywołanie funkcji iloraz()
  if (!$wynik) echo 'Nie ma dzielenia przez zero!';
  else echo 'iloraz = '.$wynik.'<br />';
?>

Przeanalizuj komentarze, które tłumaczą budowę i działanie skryptu.

Ćwiczenie 1_9_0_3. Wykonanie prostego kalkulatora

Zastosuj pokazany poniżej kod w pojedynczym pliku *.php.

<!doctype html>
<html>
  <head>
    <title>Testowanie skryptów PHP</title>
    <meta charset="UTF-8" />
  </head>
  <body>
    <?php
      function suma($x,$y)//oblicza sumę
      {
        return $x+$y;
      }
      function roznica($x,$y)//oblicz różnicę
      {
        return $x-$y;
      }
      function iloczyn($x,$y)//oblicza iloczyn
      {
        return $x*$y;
      }
      function iloraz($x,$y)//oblicza iloraz
      {
        if ($y==0) return 'Nie ma dzielenia przez zero!'; else return $x/$y;
      }
      function wyslano_formularz()//czy wciśnięto przycisk rowna_sie
      {
        return isset($_POST['rowna_sie']);
      }
      function wartosc_liczby($nr)//co ma być w polach typu text
      {
        $wynik=''; if (!wyslano_formularz()) return $wynik;//po return koniec funkcji 
        if (isset($_POST['liczba_1']) && $nr===1) $wynik=$_POST['liczba_1']; else 
        if (isset($_POST['liczba_2']) && $nr===2) $wynik=$_POST['liczba_2']; 
        return $wynik;
      }
      function wartosc_elementu_select()
      {
        if (!wyslano_formularz()) return '';
        if (!isset($_POST['znaki'])) return '';
        return $_POST['znaki'];
        //ta wartość musi być w pierwszym polu option
        //aby była pokazana
      }
      function wynik_dzialania()
      {
        $wynik=''; 
        if (!wyslano_formularz()) return $wynik;//i na tym kończy się funkcja
        $liczba1=wartosc_liczby(1);
        $liczba2=wartosc_liczby(2);
        $znak=wartosc_elementu_select();

        if ($znak=='+') $wynik=suma($liczba1,$liczba2); else 
        if ($znak=='-') $wynik=roznica($liczba1,$liczba2); else 
        if ($znak=='*') $wynik=iloczyn($liczba1,$liczba2); else 
        if ($znak=='/') $wynik=iloraz($liczba1,$liczba2); 
        
        return $wynik;        
      }
    ?>

    <form action="" method="post">
      <input type="text" name="liczba_1" value="<?php echo wartosc_liczby(1);?>" />
      <select name="znaki">
        <option value="<?php echo wartosc_elementu_select();?>"><
            ?php echo wartosc_elementu_select();?></option>
        <option value="+">+</option>
        <option value="-">-</option>
        <option value="*">*</option>
        <option value="/">/</option>
      </select>
      <input type="text" name="liczba_2" value="<?php echo wartosc_liczby(2);?>" />
      <input type="submit" name="rowna_sie" value="=" />
      
      <?php
        echo wynik_dzialania();
      ?> 
    </form>
  </body>
</html>

Zwróć uwagę że:

  • Zastosowano jeden plik, w którym znajduje się zarówno formularz, jak i skrypt PHP. Ponieważ atrybut formularza action="" jest pusty, nastąpi odświeżenie strony.
  • Kod PHP może być osadzany w kilku miejscach strony, m. in. dzięki temu w podanym przykładzie wpisane liczby oraz znak działania nie znikają, lecz są pokazywane razem z wynikiem.
  • W układzie jednego pliku, należy sprawdzić czy ma miejsce "zwykłe" ładowanie strony, czy też jej odswieżenie po wysłaniu formularza, w tym przykładzie zadanie to, wykonuje funkcja wyslano_formularz().

Praca domowa

Zdefiniuj i zastosuj w skrypcie własną funkcję.


Jeżeli zapomniałeś jak przygotować i gdzie zapisywać pliki testowe: