Funkcje

Funkcja jest kawałkiem kodu, który można wywołać podając jej nazwę. Już wcześniej podane zostało kilka funkcji dostarczanych przez PHP, takich jak array(), each(), list(), explode() czy implode(). Jak można zauważyć, funkcje rozpoznaje się po nawiasach występujących po ich nazwie. W nawiasach tych (jeśli funkcja tego wymaga) podaje się parametry dla danej funkcji. Niektóre funkcje zwracają jakąś wartość, a więc wywołanie takiej funkcji można wstawić jak dowolne inne wyrażenie do listy parametrów innej funkcji czy np. do obliczenia.

Programista może też tworzyć własne funkcje.

Przykład 6.1. Definicja funkcji


<?php

function suma($parametr1 = 0, $parametr2 = 0)
{

   $wartosc = $parametr1 + $parametr2;

   return $wartosc;

}

?>

            

Jak widać, definiowana jest funkcja o nazwie suma. SÅ‚uży ona do obliczania sumy dwóch wyrażeÅ„ podawanych jako parametry (kolejne parametry oddziela siÄ™ przecinkiem). W przypadku pominiÄ™cia któregoÅ› z parametrów przypisana mu bÄ™dzie wartość 0 – dzieje siÄ™ tak dziÄ™ki zaznaczeniu ” = 0″ po okreÅ›leniu nazwy parametru w definicji funkcji (nie jest to konieczne). Z parametrów funkcji można korzystać jak z dowolnej innej zmiennej, ale oczywiÅ›cie tylko wewnÄ…trz tej funkcji. WewnÄ…trz funkcji dostÄ™pne sÄ… tylko zmienne w niej definiowane i parametry. Można siÄ™ dostać też do innych zmiennych, ale o tym w punkcie „ZasiÄ™g zmiennych”. Do okreÅ›lania co jest zwracane przez funkcjÄ™ sÅ‚uży instrukcja return. Może ona być wywoÅ‚ana w dowolnym miejscu funkcji – po dojÅ›ciu do tej instrukcji koÅ„czy siÄ™ wykonanie funkcji.

Funkcja może nie zwracać żadnych wartości. Taka funkcja przydaje się jeśli często powtarzany jest jakiś fragment kodu. Taka funkcja kończy swoje wykonanie po dojściu do końca jej definicji lub instrukcji return (tym razem wywoływanej bez parametru, ponieważ funkcja nie zwraca żadnych wartości).

Funkcje w PHP nie mogÄ… być ponownie definiowane. MogÄ… być definiowane w zasadzie w dowolnym miejscu kodu. WewnÄ…trz funkcji znajdować siÄ™ może dowolny, prawidÅ‚owy pod wzglÄ™dem skÅ‚adniowym kod – nawet definicje innych funkcji czy klas.

Klasy

Klasy sÄ… Å›ciÅ›le zwiÄ…zane z pojÄ™ciem obiektowych zasad pisania aplikacji. JeÅ›li ktoÅ› nie spotkaÅ‚ siÄ™ jeszcze z takÄ… koncepcjÄ…, to postaram siÄ™ jÄ… objaÅ›nić w kilku zdaniach. Obiekt, tak jak w rzeczywistoÅ›ci, posiada swoje wÅ‚aÅ›ciwoÅ›ci i można z nim zrobić różne rzeczy. Klasa nie jest obiektem, ale jego definicjÄ… (np. klasÄ… jest kamieÅ„, ale nie jego konkretny egzemplarz). Definicja klasy zawiera zmienne (wÅ‚aÅ›ciwoÅ›ci obiektu) i funkcje (rzeczy, które można zrobić z tymi obiektami). Za pomocÄ… takiej konwencji programistycznej czasem można Å‚atwiej i naturalniej opisać interakcje miÄ™dzy obiektami. Oto jak siÄ™ definiuje przykÅ‚adowÄ… klasÄ™ i przykÅ‚adowe dziaÅ‚ania na niej – jako że to tylko przykÅ‚ad to i klasa nie jest zbyt ambitna.

Przykład 6.2. Przykład definicji klasy


<?php

// PoczÄ…tek definicji klasy Koszyk - definiujÄ…cej koszyk sklepowy
class Koszyk
{

// Definicja zmiennej - tablicy asocjacyjnej zawierającej numery artykułów i
// ich ilość
var $artykuly;

// Metoda dodająca podaną ilość artykułów do koszyka

   function dodaj($numer, $ilosc)
   {

      $this->artykuly["$numer"] += $ilosc;

   }

// Metoda usuwająca podaną ilość artykułów z koszyka

   function usun($numer, $ilosc)
   {

      if($this->artykuly["$numer"]>$ilosc)

         $this->artykuly["$numer"]-=$ilosc;

      else

         $this->artykuly["$numer"]=0;

   }

// Metoda wyświetlająca zawartość koszyka

   function wyswietl()
   {

      while(list($k, $v) = each($this->artykuly))
         if($v>0)
            echo "Artykul nr $k - $v sztuk<br>";

   }

}

// Przykład wykorzystania

$koszyk = new Koszyk;
$koszyk->dodaj('20', 2);
$koszyk->dodaj('12', 4);
$koszyk->dodaj('20', 5);
$koszyk->usun('12', 4);
$koszyk->wyswietl();
?>

            

Jak widać na zaÅ‚Ä…czonym przykÅ‚adzie, aby dostać siÄ™ do zmiennej lub funkcji bÄ™dÄ…cej skÅ‚adowÄ… klasy należy użyć operatora „->”. WewnÄ…trz funkcji należącej do klasy zmienna $this oznacza wÅ‚aÅ›nie ten obiekt – należy używać go chcÄ…c odwoÅ‚ać siÄ™ do zmiennej lub funkcji należącej do klasy.

W obiektowej koncepcji programowania znajduje siÄ™ takie pojÄ™cie jak dziedziczenie. Jako że w PHP obiektowość jest bardzo uboga, tak wiÄ™c i dziedziczenie jest bardzo uproszczone. Ogólnie rzecz mówiÄ…c dziedziczenie sÅ‚uży do tworzenia nowych klas na podstawie innych, rozszerzajÄ…c ich możliwoÅ›ci. Do naszej klasy można dodać nowy atrybut – nazwÄ™ wÅ‚aÅ›ciciela (zakÅ‚adam, że przed podanym listingiem w pliku znajduje siÄ™ definicja klasy Koszyk).

Przykład 6.3. Przykład dziedziczenia


<?php

class Nazwany_koszyk extends Koszyk{
   
   var $nazwa;
   
   function ustaw_nazwe($nowa_nazwa)
   {
   
      $this->nazwa = $nowa_nazwa;
   
   }
}

$koszyk = new Nazwany_koszyk;
$koszyk->ustaw_nazwe('Fredzio');
$koszyk->dodaj('2', 34);
echo 'Właściciel: '.$koszyk->nazwa.'<br/>';
$koszyk->wyswietl();

?>

            

Kolejnym pojÄ™ciem z zakresu obiektowoÅ›ci jest konstruktor. Konstruktor jest to funkcja o takiej samej nazwie jak klasa, która ustala poczÄ…tkowe wartoÅ›ci zmiennych (wywoÅ‚ywana jest automatycznie przy tworzeniu obiektu). Konstruktorowi można podać pewne wartoÅ›ci przy tworzeniu obiektu. Oto kolejna wersja koszyka wyposażona w konstruktor, który ustawia nazwÄ™ wÅ‚aÅ›ciciela na podanÄ… lub „Anonim” jeÅ›li jej nie podano:

Przykład 6.4. Zastosowanie konstruktora


<?

class Auto_koszyk extends Nazwany_koszyki
{

   function Auto_koszyk( $nazwa = 'Anonim')
   {
   
      $this->ustaw_nazwe($nazwa);
   
   }
}

$koszyk = new Auto_koszyk('Jakiś właściciel');
$koszyk->dodaj('4', 30);
echo 'Właściciel: '.$koszyk->nazwa.'<br/>';
$koszyk->wyswietl();

?>

            

Instrukcje include i require

W PHP istniejÄ… dwie instrukcje, które pozwalajÄ… wÅ‚Ä…czyć do kodu zawartość innego pliku także zawierajÄ…cego kod PHP. Obu tym instrukcjom podaje siÄ™ jeden parametr – nazwÄ™ pliku do wÅ‚Ä…czenia do kodu (może to być Å›cieżka do pliku znajdujÄ…cego siÄ™ na innym serwerze WWW). Różnica miÄ™dzy nimi polega na sposobie wÅ‚Ä…czania tych plików do kodu. W przypadku instrukcji require pliki doÅ‚Ä…czane sÄ… do kodu jeszcze przed parsowaniem, w każdym miejscu gdzie znajduje siÄ™ instrukcja require. Dlatego instrukcja ta nie nadaje siÄ™ do doÅ‚Ä…czania plików których nazwa pobierana jest ze zmiennej – zamiast tego należy użyć instrukcji include. UżywajÄ…c tych instrukcji należy pamiÄ™tać o dwóch rzeczach. Po pierwsze, przetwarzanie plików zaincludowanych zaczyna siÄ™ od trybu HTML, a wiÄ™c jeÅ›li plik zawiera tylko kod PHP, to powinien zaczynać siÄ™ od jednego ze znaczników otwierajÄ…cych. Po drugie należy pamiÄ™tać, że jeÅ›li instrukcja include używana jest w pÄ™tli lub instrukcji warunkowej, to pomimo że jest to teoretycznie jedna linia, to musi znajdować siÄ™ ona w nawiasach klamrowych, ponieważ ta pojedyncza linia zamieniana jest na wiele linii doÅ‚Ä…czanych z innego pliku.

Funkcja readfile()

Innym typem funkcji służącej do dołączania treści zawartych w innym pliku jest funkcja readfile(). Rzeczą odróżniającą tą funkcję od instrukcji zawartych w poprzednim punkcie jest to, że dane pobrane z pliku nie są przetwarzane przez PHP, więc funkcja ta nadaje się tylko do wyświetlania plików HTML bądź czysto tekstowych.

Zasięg zmiennych

Przy korzystaniu z funkcji i klas pojawia się problem zasięgu zmiennych. Problem ten dotyczy większości języków programowania. Ogólnie mówiąc chodzi o to, że zmienne dostępne są zazwyczaj tylko w tym zasięgu, w którym zostały zdeklarowane. Przez zasięg rozumiem zasięg główny (to znaczy część kodu, która nie należy do żadnej funkcji lub klasy), klasy i funkcje.

Przykład 6.5. Zasięg zmiennych


<?php

$a = 34;

function aaa()
{

   echo $a;

}

aaa();

?>

            

Pomimo, że zmienna $a została zadeklarowana wcześniej, to nic się nie wyświetli, ponieważ zmienna $a nie jest dostępna wewnątrz funkcji. Dostęp do zmiennych globalnych można uzyskać na 2 sposoby. Po pierwsze, można powiadomić PHP że dana zmienna ma być pobierana z zasięgu głównego za pomocą instrukcji global.

Przykład 6.6. Zmiana zasięgu zmiennej


<?

$a = 23;

function aaa()
{
   global $a;
   
   echo $a;
   
}

aaa();

?>

            

W tym przykładzie zostanie wyświetlona prawidłowa wartość zmiennej $a. Istnieje też druga metoda dostania się do zmiennych globalnych. W każdym miejscu kodu dostępna jest tablica asocjacyjna $GLOBALS, której kluczami są nazwy zmiennych dostępnych w zasięgu głównym.

Istnieje jeszcze jeden aspekt dotyczący zasięgu zmiennych: zmienne statyczne.

Przykład 6.7. Zmienna statyczna


<?

function aaa()
{
   
   $a = 0;
   
   echo $a;
   
   $a++;
}

aaa();
aaa();
aaa();

?>

            

Powyższy przykÅ‚ad jest w zasadzie bez sensu – za każdym razem wyÅ›wietlona bÄ™dzie wartość 0, ponieważ za każdym wywoÅ‚aniem funkcji zmienna $a bÄ™dzie od nowa inicjowana wartoÅ›ciÄ… 0 a po wyÅ›wietleniu i inkrementacji tej zmiennej bÄ™dzie ona niszczona (wszystkie zmienne inicjowane w funkcji oprócz statycznych sÄ… niszczone po wykonaniu siÄ™ funkcji).

Przykład 6.8. Zmiana zasięgu zmiennej


<?

function aaa()
{

   static $a = 0;
   
   echo $a;
   
   $a++;
   
}

aaa();
aaa();
aaa();

?>

            

Natomiast w tym przykładzie wyświetlone zostaną wartości 0, 1 i 2. Dzieje się tak, ponieważ mimo że zmienna jest inicjowana wartością 0, to dzięki instrukcji static dzieje się to tylko raz, a do tego po zakończeniu wykonywania się funkcji zmienna ta nie jest niszczona.

W PHP 4.1.0 wprowadzone zostaÅ‚y tak zwane tablice superglobalne. SÄ… one tworzone przez PHP – użytkownik nie może samemu tworzyć takich tablic. ZawierajÄ… one dane przekazywane do PHP metodami GET, POST, informacje o przekazanych plikach, dane z ciasteczek i sesji – odpowiedno $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION. MajÄ… one zastÄ…pić tablice $HTTP_*_VARS, które ze wzglÄ™du na kompatybilność sÄ… jeszcze obecne. Różnica miÄ™dzy tablicami superglobalnymi a tymi używanymi wczeÅ›niej jest taka, że tablice superglobalne dostÄ™pne sÄ… w dowolnym miejscu kodu, bez potrzeby użycia instrukcji global.