Programowanie w języku PHP

Podstawy PHP

  • 2006-03-07 12:55
  • 5 komentarzy
  • 3865 odsłon
  • Oceń ten tekst jako pierwszy
Wiesz już, czym jest PHP, czym charakteryzują się języki skryptowe oraz jak zainstalować PHP. Pewnie masz już gotowy serwer, przystosowany do programowania w PHP z wykorzystaniem MySQL. Zajmijmy się podstawową składnią PHP, konstrukcją prostych skryptów.

Spis treści

     1 Skrypty PHP
     2 Instrukcje
          2.1 Instrukcja echo
               2.1.1 Długie łańcuchy znaków
          2.2 Instrukcja print
          2.3 Wyświetlanie kodu HTML
     3 Komentarze
     4 Literały
          4.1 Literały tekstowe
          4.2 Literały liczbowe
          4.3 Literały logiczne
     5 Praca ze zmiennymi
          5.1 Przypisanie danych
          5.2 Odwołanie do zmiennej
          5.3 Zmienne zmienne
     6 Stałe
          6.1 Typy danych
          6.2 Funkcja settype()
          6.3 Rzutowanie
     7 Operatory
          7.1 Operatory inkrementacji i dekrementacji
          7.2 Operatory łańcuchowe
          7.3 Operatory przypisania
          7.4 Operatory arytmetyczne
               7.4.1 Zaokrąglanie
          7.5 Operatory porównania
          7.6 Operatory logiczne
          7.7 Operatory wykonania polecenia systemowego
          7.8 Operatory kontroli błędów
          7.9 Operatory bitowe
          7.10 Priorytety operatorów
     8 Instrukcje warunkowe
          8.1 Instrukcja if
               8.1.1 Blok instrukcji
          8.2 Instrukcja else
          8.3 Instrukcja elseif
          8.4 Konstrukcja if..endif
          8.5 Operator trójoperandowy
          8.6 Instrukcja switch
     9 Pętle
          9.1 Pętla while
          9.2 Pętla do..while
          9.3 Pętla for
          9.4 Pętle forever
          9.5 Pętla for działająca w drugą stronę
          9.6 Pętla foreach
          9.7 Instrukcje continue i break
     10 Funkcje
          10.1 Parametry funkcji
          10.2 Parametry domyślne
          10.3 Zmienne lokalne
               10.3.1 Zakres zmiennej
          10.4 Czas życia zmiennej
          10.5 Funkcje zagnieżdżone
     11 Programowanie strukturalne
          11.1 Włączanie modułów w ciało funkcji
     12 Operacje na łańcuchach
               12.1 sprintf
          12.1 strtolower, strtoupper
          12.2 trim
          12.3 strlen
          12.4 chr, ord
          12.5 nl2br
          12.6 str_replace
          12.7 strstr
          12.8 substr
          12.9 strpos
     13 Referencje
          13.1 Przekazywanie przez referencje


Składnia to specyficzne dla języka słowa, znaki, które są analizowane przez parser. Składnia naszego programu musi podlegać pewnym standardom tak, aby parser rozpoznał instrukcje i zareagował zgodnie z ich przeznaczeniem.

Parser (inaczej analizator składniowy) to narzędzie, które analizuje składnie pliku.

Skrypty PHP


Skrypty PHP najczęściej posiadają rozszerzenie *.php i są tworzone przy pomocy dowolnego edytora tekstów. Skrypty PHP mogą być zwykłymi plikami, w których zagnieżdżone są instrukcje PHP.

Parser PHP wykonuje kod, który znajduje się pomiędzy instrukcjami <?php i ?>. Oto przykład:

Trzy razy trzy jest <?php echo(3 * 3) ?>


Po wpisaniu powyższej linijki do edytora i zapisaniu pod nazwą ? np. test.php, przeglądarka wyświetli napis: Trzy razy trzy jest 9. Instrukcja echo umożliwia wyświetlenie tekstu. Równie dobrze można wykorzystać instrukcje print, która jest z pewnością znana osobom programującym wcześniej w Perlu. Nawiasy przy instrukcji echo są opcjonalne, więc skrypt realizujący mnożenie liczby 3 mógłby wyglądać również tak:

Trzy razy trzy jest <?php echo 3 * 3 ?>


Zamiast znaczników <?php ?> informujących o rozpoczęciu kodu PHP, można stosować ich skrócone wersje:

Trzy razy trzy jest <? echo 3 * 3 ?>


Taki zapis będzie działał tylko wtedy, gdy włączona została opcja short_open_tag w pliku php.ini. Pomimo, iż dwa zaprezentowane tutaj sposoby zagnieżdżania kodu PHP są najprostsze, istnieją jeszcze inne możliwości, rzadziej spotykane. Jednym z takich sposób, jest zastosowanie znaków otwierających w "stylu" ASP:

Trzy razy trzy jest <% echo 3 * 3 %>


Taki zapis będzie działał jedynie w przypadku, gdy uaktywnimy odpowiednią opcję (asp_tags) w pliku php.ini.

Uwaga! Opcja asp_tags jest domyślnie wyłączona!

Chyba najrzadziej stosowaną opcją jest używanie znacznika <script> w celu określenia, że mamy do czynienia z kodem PHP. Takie znaczniki stosuje się dla edytorów typu WYSIWYG (np. FrontPage) które nie lubią instrukcji PHP zagnieżdżonych w kod HTML. Oto przykład:

<html>
<head>
<body>
 
Trzy razy trzy jest
<script language="PHP">
   echo 3 * 3;
</script>
 
</head>
</body>


WYSIWYG to akronim od What You See Is What You Get (ang. Masz to co widzisz). Programy WYSIWYG mają odzwierciedlać na ekranie końcowy rezultat prac. Np. edytory HTML WYSIWYG umożliwiają stały podgląd rezultatu w trakcie projektowania strony.

Instrukcje


Programowanie opiera się na stosowaniu instrukcji języka, czytelnych dla parsera. W większości języków programowania jest tak, że instrukcje muszą być oddzielone od siebie znakiem średnika (;). Przykład:

<?
  echo 3 * 3; echo 4 * 3; 
?>


W powyższym przykładzie mamy do czynienia z dwoma instrukcjami echo. Pierwsza z nich zwróci do przeglądarki wynik mnożenia 3 przez 3, a druga wynik mnożenia 4 przez 3.

Po uruchomieniu takiego skryptu, w przeglądarce ujrzymy liczbę 912. Pytanie: skąd ona tam się wzięła? Zwyczajnie jest to zlepek dwóch liczb ? 9 i 12 (wyników  mnożenia).

Z punktu widzenia parsera nie ma znaczenia czy umieścimy obie instrukcje jedna pod drugą, czy obok siebie. Tak więc oba wywołania są sobie równe:

<?
   echo 3 * 3;
   echo 4 * 3;
?>
<?
   echo 3 * 3;echo 4 * 3;
?>


Ze względu na czytelność kodu, zalecana jest pierwsza metoda, czyli zapisywanie instrukcji jedna pod drugą.

Naturalnie nie ma także znaczenia liczba spacji, odstępy między instrukcjami ? wszystko to jest akceptowane przez parser. W związku z tym poniższy skrypt zostanie wykonany poprawnie:

<?
  echo(3*3);
  echo 4    * 10;
  echo(
      76
      *
      3);
 
?> 


Co ciekawe jeżeli wewnątrz znaczników <? ?> znajdzie się jedna instrukcja, to nie jest konieczne zakończenie jej znakiem średnika ? np.:

<? echo 2 + 2 ?>


Instrukcja echo


Instrukcja języka PHP ? echo jest z pewnością najczęściej używana. Umożliwia ona wysłanie tekstu do przeglądarki. Ponieważ język PHP jest bardzo elastyczny (w przeciwieństwie do np. Delphi), instrukcji echo można używać na wiele sposobów. Przyjrzyjmy się przez moment nad zastosowaniem tej instrukcji.

Instrukcja echo umożliwia wyświetlanie, nie tylko liczb, wyniku działań matematycznych, ale także ? co chyba najważniejsze ? tekstu. Tekst należy jednak ująć w apostrofy lub cudzysłowy:

<?
  echo("Hello World!");
  echo('Hello World!');
?>


Obie instrukcje przedstawione wyżej są równoważne. Jeżeli chodzi o nawiasy to jak wspomniałem wcześniej ? są one opcjonalne, lecz jeżeli mimo to chcesz z nich korzystać, to PHP nie narzuca konwencji ich stosowania. Poniższy skrypt jest więc prawidłowy:

<?
  echo (
  "Hello World!"
  );
 
  echo ( 'Hello World!' );
?>


Ja jednak, w tej książce będę korzystał przeważnie z takiego wywołania:

<?
  echo 'Hello World!';
?>


Długie łańcuchy znaków


Podsumujmy: jeżeli chcemy wyświetlić tekst, musimy zawrzeć go w apostrofach lub cudzysłowach. Taka konstrukcja nazywa się łańcuchem znaków (ang. string). Często możesz się spotkać z wypowiedzią: Wyświetlam łańcuch... Teraz będziesz już wiedział, że chodzi tutaj o tekst zawarty w apostrofy lub cudzysłowy.

W PHP nic nie stoi na przeszkodzie, aby łańcuch zapisać w kilku liniach ? np.:

<?
  echo '
    To jest łańcuch, który nie mieści się w jednej linii, więc
    trzeba zapisać go w dwóch linijkach.
  ';
?>


Należy jednak pamiętać o zakończeniu łańcucha! Np. poniższa instrukcja zostanie źle zinterpretowana:

<?
  echo "
    To jest łańcuch, który nie mieści się w jednej linii, więc
    trzeba zapisać go w dwóch linijkach.
  ';
?>


Wszystko dlatego, że tutaj łańcuch rozpoczyna się od znaku cudzysłowie, a kończy apostrofem! Podczas próby wykonania takiego skryptu PHP wyświetli błąd: Parse error: parse error, unexpected $end.
Istnieje jeszcze jedna, mniej popularna metoda zapisywania długich łańcuchów:

<?
echo <<<END
To jest łańcuch, który nie mieści się w jednej linii, więc
trzeba zapisać go w dwóch linijkach.
END;
?>


Działa pod warunkiem, iż łańcuch rozpocznie się i zakończy tym samym słowem ? w tym wypadku ? END. Nie jest to jednak metoda często spotykana.

Należy zauważyć, że, mimo iż w skrypcie łańcuch jest podzielony na dwie linijki to w przeglądarce i tak całość zostanie wyświetlona w jednej linii. Wszystko, dlatego, iż przeglądarki jako znak nowej linii rozpoznają znacznik HTML -
lub </br> w XHTML. O tym będzie mowa w dalszej części.

Instrukcja print


Z pewnością wiele osób używa instrukcji print jako alias do instrukcji echo. Pomimo, iż obie wysyłają tekst, mają nieco odrębne działanie. Jest to, co prawda prawie niezauważalne, lecz warto o tym wspomnieć jako o ciekawostce. Instrukcja print oprócz tego, że wysyła tekst, zwraca zawsze liczbę 1. Oto przykład:

<?
  print print "Adam";
?>


W skutek działania takiego skryptu na ekranie przeglądarki wyświetli się napis: Adam1. Takie samo działanie miałaby taka instrukcja:

echo print "Adam";


Zwyczajnie print oprócz tego, że wyświetla napis Adam, zwraca liczbę 1, którą wyświetlamy korzystając z polecenia echo.

Jeżeli chodzi o instrukcje echo, to ma nieco inne działanie ? nie zwraca żadnych wartości, przez co jej użycie jest minimalnie szybsze. Można natomiast użyć jej w taki sposób:

<?
  echo "Adam", "Boduch";
?>


Powyższa instrukcja spowoduje wysłanie do przeglądarki napisu AdamBoduch. Dwie części łańcucha oddzieliłem od siebie przecinkiem, lecz Ty nie będziesz pewnie stosował takiej konstrukcji zbyt często. Te informacje podaje raczej jako ciekawostkę.

W tym artykule będę korzystał z instrukcji echo. Jeżeli jednak jesteś przyzwyczajony do print, nie jest konieczne abyś zmieniał swoje przyzwyczajenia.

Wyświetlanie kodu HTML


Instrukcje PHP mogą, i często są zagnieżdżane wewnątrz kodu HTML. Dzięki temu możemy stworzyć dynamiczną stronę, ale i także skorzystać z formatowania HTML w celu upiększenia strony. Przykład:

<html>
<head>
<title>Skrypt PHP</title>
</head>
 
<body>
<p>2 + 2 jest <b><? echo 2 + 2 ?></b></p>
</body>
</html> 


Dzięki temu rezultat dodawania 2 do dwóch będzie pogrubiony (dzięki zastosowaniu znacznika <b>). Nic nie stoi na przeszkodzie, aby taki sam rezultat osiągnąć wyświetlając kod HTML poprzez instrukcję echo:

<?
  echo "<html>";
  echo "<head>";
  echo "<title>Skrypt PHP</title>";
  echo "</head>";
  echo "<body>";
  echo "<p>2 + 2 jest <b>";
  echo 2 + 2;
  echo "</b></p>";
  echo "</body>";
  echo "</html>";
?>


Wydaje mi się jednak, że przejrzystsze jest zagnieżdżanie instrukcji PHP wprost w kod HTML. Ale, do czego zmierzam? Otóż jak zapewne Ci wiadomo, znaczniki HTML mogą posiadać parametry, które należy zapisać w cudzysłowie. Przykładowo, chcemy, aby znacznik <p> posiadał parametr style. W takim wypadku naturalnym byłoby zastosowanie takiego kodu:

echo "<p style="margin: 10">2 + 2 jest <b>";


Parser PHP napotykając znak cudzysłowia, uzna, że jest to koniec łańcucha. Wykonanie takiego skryptu zakończy się komunikatem błędu Parse error: parse error, unexpected T_STRING, expecting ',' or ';'. Pamiętaj! Jeżeli chcesz, aby znak " stanowił część łańcucha musisz poprzedzić go znakiem backslasha (\) w taki oto sposób:

echo "<p style=\"margin: 10\">2 + 2 jest <b>";


Innym rozwiązaniem jest użycie apostrofów zamiast cudzysłowie. W łańcuchach ograniczonych apostrofem może znajdować się znak "

echo '<p style="margin: 10">2 + 2 jest <b>';


Komentarze


Komentarze są elementem składni obecnym w każdym języku programowania. Komentarze to sposób, aby zawrzeć w kodzie źródłowym własne przemyślenia, pomysły dotyczące kodu, czy też prawa autorskie. Przeważnie są stosowane do opisu kodu, wytycznych, co robi dana linia. Komentarze są całkowicie ignorowane przez interpreter.

Istnieje kilka sposób komentowania kodu. Najprostszym z nich jest komentarz jednej linii:

<?
  echo 'Hello World!'; // przywitanie
?>


Komentarz jednoliniowy rozpoczyna się od znaków // i obowiązuje do końca danej linii. To samo można osiągnąć stosując znak # (jest to komentarz obowiązujący w Perlu):

<?
  echo 'Hello World!'; # przywitanie
  // koniec skryptu
?>


Takie typy komentarzy obowiązują jedynie na długości jednej linii, więc problematyczne staje się komentowanie większego bloku tekstu. Rozwiązaniem jest stosowanie jeszcze jednego typu komentarzy, w stylu C++, którego początek stanowią znaki /* a koniec znaki */:

<?
  /*
     początek komentarza 
     echo 'Hello World!';
     powyższa instrukcja nie zostanie wykonana
  */
?>


Należy zaznaczyć różnicę pomiędzy komentarzami typowymi dla PHP oraz komentarzami HTML. Przykład:

<?
  // a tu będzie komentarz
  echo 'Hello World!';
?>
 
// to już nie będzie komentarz
 
<!--to jest komentarz-->


Po wykonaniu takiego skryptu możesz spojrzeć na źródło wygenerowanej strony (każda przeglądarka ma opcję Pokaż źródło). Zobaczysz, że komentarz jednoliniowy nie został usunięty:

Hello World!
// to już nie będzie komentarz
 
<!--to jest komentarz-->


Wszystko dlatego, że zastosowaliśmy go poza blokiem <? ?>, a tam funkcjonuje już jako zwykły tekst. Przeglądarki internetowe nie interpretują instrukcji pomiędzy znakami <!-? oraz --> które są brane jako komentarz.

Literały


Pojęcie literału, w językach programowania oznacza wartość wpisaną w kod programu. Literałem jest łańcuch Hello World, który wykorzystywałem nagminnie. PHP rozróżnia kilka podstawowych typów literałów: tekstowe, liczbowe, logiczne. Przyjrzyjmy się pokrótce każdemu z nich.

Literały tekstowe


Literały tekstowe to zwykłe napisy, łańcuchy tekstowe. Napisy można przedstawiać w apostrofach lub cudzysłowach.

Jeżeli tekst jest zamknięty w cudzysłowy, PHP przetwarza go w poszukiwaniu znaków specjalnych. Takimi znakami specjalnymi może być np. oznaczenie nowej linii (\n) lub znak tabulacji (\t). Spójrz na następujący skrypt:

<?
  echo "Pierwsza linia \n Druga linia \n Trzecia linia";
?>


Gdy uruchomisz taki skrypt w przeglądarce to i tak cały tekst zostanie zapisany w jednej linii, gdyż przeglądarki nie są wrażliwe na znaki nowej linii w kodzie. Możesz jednak zobaczyć na kod wygenerowanej strony, aby zobaczyć, że jednak linie zostały zapisane jedna pod drugą:

Pierwsza linia 
 Druga linia 
 Trzecia linia


Gdybyś zamiast cudzysłowie użył apostrofów, to znak nowej linii (\n) zostałby potraktowany jako zwykły tekst:

  echo 'Pierwsza linia \n Druga linia \n Trzecia linia';


W przeglądarce otrzymasz:

Pierwsza linia \n Druga linia \n Trzecia linia


Przeglądarki internetowe interpretują znaczniki HTML. W HTML znacznikiem, który nakazuje łamanie linii jest
(lub
w XHTML), tak więc chcąc wyświetlić tekst w nowej linii musiałbyś skorzystać z takiej instrukcji:

echo "Pierwsza linia <br> Druga linia <br> Trzecia linia";


Możesz także użyć funkcji nl2br() która analizuje łańcuch tekstowy w poszukiwaniu znaków nowej linii i zamienia owe znaki na znaczniki
:

echo nl2br("Pierwsza linia \n Druga linia \n Trzecia linia");


Literały liczbowe


PHP obsługuje liczby całkowite oraz zmiennoprzecinkowe. Oto kilka przykładów wyświetlenia liczb:

<?
echo 255;
echo 255.34;
echo ?255.45; // wartość ujemna
?> 


Ciekawostką jest fakt, że liczby całkowite można przedstawiać w notacji dziesiętnej, ósemkowej lub szesnastkowej. Instrukcja echo zawsze wypisze liczby całkowite w notacji dziesiętnej, więc poniższe instrukcje wypiszą liczbę 255:

<?
echo 255; // dziesiętnie
echo 0xFF; // szesnastkowo
echo 0377;  // ósemkowo
?>


Literały logiczne


W wielu językach programowania obowiązują słowa kluczowe true oraz false. To są właśnie literały logiczne oznaczające prawdę (true) lub fałsz (false). Dla PHP nie ma znaczenia wielkość liter więc równie dobrze możesz napisać false, False czy FALSE.

Praca ze zmiennymi


Zmienne to kolejny element języka dostępny praktycznie w każdym języku programowania. Stanowi on swoisty pojemnik na dane. W każdym momencie możemy zadeklarować zmienną, przypisać jej dane, aby później ów dane odczytać.

Zmienne w PHP deklaruje się w bardzo prosty sposób, z użyciem znaku dolara ($):

<?
  $var;
?>


Każda zmienna musi posiadać swoją nazwę, która będzie unikalna w skali programu. Nazwa zmiennej może składać się z dowolnych znaków, pod warunkiem, iż pierwszym znakiem nie będzie liczba. Nazwa zmiennej może składać się z polskich znaków, więc nic nie stoi na przeszkodzie deklaracji takiej oto zmiennej:

$_gżegżółka;

W przeciwieństwie do słów kluczowych, PHP odróżnia wielkość liter zmiennych tak więc $_gżegżółka oraz $_Gżegżółka będą stanowiły dwie odrębne zmienne.

Przypisanie danych


W poprzednich deklarowałem zmienne bez przypisania im konkretnych danych. Pomimo iż taka konstrukcja jest prawidłowa, PHP może wyświetlać wiadomość: Notice: Undefined variable: _gżegżółka.

Jeżeli programowałeś wcześniej w innych językach możesz być zaskoczony tym, że PHP nie wymaga określania typu dla zmiennej. Oznacza to, że jedna zmienna może zawierać dane w postaci liczbowej, tekstowej lub logicznej.

Zmienne są po to, aby przechowywać dane w pamięci. Przypisanie danych do zmiennej odbywa się przy pomocy operatora przypisania (=). Oto przykład:

<?
$var = 10;
$var = 'Tekst';
$var = true;
?>


Powyższy kod jest jak najbardziej poprawny. Na początek do zmiennej przypisujemy liczbę 10, później tekst, a końcu wartość logiczną true.
Istnieje również możliwość przypisania do zmiennej wartości pochodzącej z innej zmiennej:
<?
  $var1 = 'Napis...';
  $var2 = $var1;
?>


Takim oto sposobem posiadamy dwie zmienne ($var1, $var2), które mają taką samą wartość.

Odwołanie do zmiennej


Wyświetlenie wartości danej zmiennej jest bardzo proste. Realizuje się to przy pomocy instrukcji echo lub print:

<?
  $var1 = 'Napis...';
  $var2 = $var1;
 
  echo $var2;
?>


Zasada działania zmiennych jest stosunkowo prosta. Interpreter analizując kod źródłowy napotyka na linię, w której do zmiennej $var1 przypisujemy tekst Napis.... Następnie sprawdza, czy taka zmienna ($var1) jest już zadeklarowana w pamięci. Jeżeli nie, następuje "rezerwacja" komórki pamięci, do której przypisywana jest wartość zmiennej.

Interpreter zna adres komórki pamięci, w której zapisane zostały dane. Jeżeli chcemy wyświetlić zawartość danej zmiennej, PHP odwołuje się do danej komórki i pobiera z niej informacje. Po zakończeniu działania skryptu, pamięć zarezerwowana przez PHP jest automatycznie czyszczona.

Innym sposobem odwołania się do zmiennej jest zastosowanie klamer:

  echo ${"var1"};


Taka konstrukcja jest jednak rzadko używana, raczej w bardziej specyficznych sytuacjach. Dzięki takiemu zapisowi możliwe jest skonstruowanie takiego kodu:

<?
  $moje_imie = "Adam";
  $moje_nazwisko = "Boduch";
 
  $a = "imie";
 
  echo ${"moje_$a"};
?>


Odwołanie do zmiennych może być także umieszczone w łańcuchu, pod warunkiem, że łańcuch jest tworzony przy pomocy cudzysłowia:

<?
$moje_imie = "Adam";
echo "Moje imię to $moje_imie"; // wyświetli: Moje imię to Adam
echo 'Moje imię to $moje_imie'; // wyświetli: Moje imię to $moje_imie
?>


Zmienne zmienne


Jest to bardziej zaawansowana konstrukcja zmiennych. Polega na deklarowaniu zmiennej o dynamicznej nazwie. Normalną zmienną deklaruje się w ten sposób:

$a = "Hello";


Przy pomocy podwójnego znaku dolara, możemy zadeklarować zmienną, która będzie posiadała nazwę Hello.

<?
  $a = "Hello"; // deklaracja zmiennej $a
  $$a = "World"; // $deklaracja zmiennej $Hello
 
  echo "$a $Hello"; // wyświetli napis Hello World
?>


Stałe


Stałe również wypełniają rolę "pojemnika" na dane, lecz w odróżnieniu od zmiennych ? nie można tych danych modyfikować w trakcie działania programu.

Stałe deklaruje się przy pomocy define():

  DEFINE('AUTOR', 'Adam Boduch');


Pierwszym parametrem musi być nazwa stałej, a drugim ? jej wartość. Podobnie jak w przypadku zmiennych, również stałe mogą przybierać wartości tekstowe, liczbowe czy logiczne.

Odwołanie do stałej jest dosyć proste, wystarczy prosty kod (z pominięciem znaku dolara):

echo AUTOR;


Przyjęło się że deklarując stałe używane są wielkie litery, ale oczywiście nie jest to ograniczenie PHP.

Typy danych


Pomimo tego, że PHP jest bardzo elastyczny, do jednej zmiennej możemy przypisać dowolne dane, to istnieje możliwość ustalenia typu wcześniej. W językach takich jak C, czy Delphi przy deklaracji zmiennej musimy określić jej typ, czy będzie to liczba, czy tekst itd. PHP rozpoznaje następujące typy danych:

  • boolean ? tzw. boolowski (true lub false);
  • integer ? liczba całkowita;
  • float ? liczba zmiennoprzecinkowa;
  • string ? łańcuch;
  • array ? tablica;
  • object ? obiekt;
  • resource ? zasoby;

O tablicach, obiektach i zasobach będziemy mówić innym razem. Na razie skupmy się na podstawowych typach (tzw. typach skalarnych).

Mimo, że PHP zwykle ustala typ danych na podstawie kontekstu (czyli wartości), możemy odczytać typ danej zmiennej lub ustalić go samodzielnie. Funkcja var_dump() wyświetla informacje na typu zmiennej. Przyjrzyj się poniższemu skryptowi:

<?
  $var = 10;
  var_dump($var); // wyświetli int(10)
  $var = 'string';
  var_dump($var); // wyświetli string(6) "string"
  $var = 2.4;
  var_dump($var); // wyświetli float(2.4)
  $var = true;
  var_dump($var); // wyświetli bool(true)
?>


W połączeniu z funkcją var_dump(), nie musimy używać instrukcji echo ? funkcja var_dump() sama zajmie się wyświetleniem informacji.
Możemy także skorzystać z funkcji gettype() która zwraca typ danych znajdujących się w zmiennej:

<?
  $var = 10;
  echo gettype($var); // wyświetli integer
  $var = 'string';
  echo gettype($var); // wyświetli string
  $var = 2.4;
  echo gettype($var); // wyświetli double
  $var = true;
  echo gettype($var); // wyświetli boolean
?>


Funkcja settype()


Funkcja settype() służy do samodzielnego ustalania typu dla zmiennej. Pierwszym parametrem tej funkcji musi być nazwa zmiennej, a drugim ? łańcuch oznaczający typ danych, na który odbędzie się konwersja. Oto przykłady:

<?
  $var = 10;
  settype($var, "bool");
  echo $var; // wyświetli 1
 
  $var = '1 słońce';
  settype($var, "int");
  echo $var; // wyświetli 1
 
  $var = true;
  settype($var, "string");
  echo $var; // wyświetli 1
?>


Drugi parametr może przybrać wartości zaprezentowane w tabeli 1.

Tabela 1. Możliwe wartości drugiego parametru funkcji settype()
Wartość                                               Opis
string                                               Łańcuch tekstowy;
integer, int (od wersji PHP 4.2.0)               Liczba całkowita;
double, float (od wersji PHP 4.2.0)      Liczba zmiennoprzecinkowa;
boolean, bool (od wersji PHP 4.2.0)    Wartość logiczna;
array                                               Tablica;
object                                               Obiekt;
null (od wersji 4.2.0)                               Wartość pusta 


Słowo kluczowe NULL w PHP oznacza wartość pustą (żadne dane do zmiennej nie zostały przypisane). Przypominam, że drugi parametr funkcji settype() musi być zawarty w apostrofy lub cudzysłowy.

Rzutowanie


Rzutowanie to inaczej wymuszenie traktowania wartości jednego typu tak jakby to była wartość innego typu. Rzutowanie odbywa się poprzez podanie nazwy nowego typu w nawiasie poprzedzającym nazwę zmiennej:

<?
  $var = 10.5;
  echo (int)$var; // wyświetli 10
 
  $var = 10.5;
  echo (bool)$var; // wyświetli 1
 
  $var = 'string';
  echo (int)$var;  // wyświetli 0
?>


Wartości podane w nawiasie mogą przybrać formę taką jak w tabeli 1.

Operatory


Podczas eksperymentów z przykładami w tej książce, nie raz używałeś już operatorów. Jest to element języka służący do manipulacji danymi. Przykładowo operator + (dodawanie) służy do dodawania dwóch wartości. Operatorem jest także znak = (operator przypisania) który realizuje przypisanie danych z jednej zmiennej do drugiej. Operatory dzielą się na kilka kategorii:

  • Operatory przypisania
  • Operatory arytmetyczne
  • Operatory porównania
  • Operatory bitowe
  • Operatory logiczne
  • Operatory łańcuchowe
  • Operatory inkrementacji i dekrementacji
  • Operatory kontroli błędów
  • Operatory wykonania systemowego

Pokrótce przyjrzyjmy się tym kategoriom.

Operatory inkrementacji i dekrementacji


Operatory inkrementacji oraz dekrementacji obecne są także w językach C/C++ oraz Java i stamtąd zostały one zaczerpnięte do PHP. Służą one szybkiemu zwiększaniu oraz zmniejszaniu wartości danej zmiennej:

  $i = 10;
  --$i; // wartość $i to 9



Zasada zastosowania jest prosta. W celu zmniejszenia wartości danej zmiennej wystarczy umieścić dwa znaki odejmowania (--) przed lub za nazwą zmiennej. Możliwe są, więc takie rozwiązania:

--$i; // zmniejsz o jeden
$i--; // zmniejsz o jeden
Tak samo działa operator inkrementacji (zwiększania):
++$i; // zwiększ o jeden
$i++; // zwiększ o jeden


Położenie operatorów inkrementacji i dekrementacji ma znaczenie. Konstrukcja ++$i nazywana jest pre-inkrementacją i najpierw zwiększa wartość zmiennej, a potem zwraca $i. Konstrukcja $i++ to post-inkrementacja ? najpierw zwraca wartość $i a dopiero później zwiększa ją o 1. Najlepiej zaobserwować to na przykładzie:

<?
  $i = 10;
 
  echo $i++; // wyświetli 10 i zwiększy o jeden (do 11)
  echo '<br>';
  echo ++$i; // zwiększy o 1 i wyświetli 12
?>


Mam nadzieje, że to jest jasne. Tak samo ma się sprawa z dekrementacją. Tutaj także obowiązuje pre-dekrementacja oraz post-dekrementacja.

W rzeczywistości operator inkrementacji lub dekrementacji równy jest takiemu działaniu:

$i = $i + 1; // zwiększenie o 1
$i = $i ? 1; // zmniejszenie o 1


Operatory łańcuchowe


W PHP dostępne są dwa operatory działające na łańcuchach. Pierwszy z nich to operator połączenia (.) który umożliwia połączenie dwóch łańcuchów danych:

<?
  $imie = 'Adam';
  $nazwisko = ' Boduch';
  echo $imie . $nazwisko;
?>


Powyższy skrypt wyświetli napis Adam Boduch. Zwróć uwagę, iż wartość zmiennej $nazwisko rozpoczyna się od spacji, która po połączeniu dwóch łańcuchów jest zachowywana.

Drugi operator (.=) dokonuje połączenia łańcucha wraz z przypisaniem wartości z prawej strony do strony lewej:

<?
  $a = 'Adam';
  $a .= ' Boduch';
  echo $a; 
?>


Rezultat wykonania takiego programu jest identyczny jak poprzednim przypadku. Fraza  Boduch została "doklejona" na koniec frazy Adam.
 

Operatory przypisania


Do tej pory miałeś okazję skorzystać z jednego z operatorów przypisania (=). Oznacza on to, iż zmienna znajdująca się po jego lewej stronie otrzymuje wartość znajdującą się po stronie prawej. Operator przypisania ma większe możliwości, połączenia z operatorami arytmetycznymi oraz łańcuchowymi ? np.:

<?
  $i = 10;
  $i += 10;
?>


Operator += powoduje zwiększenie wartości zmiennej o wartość znajdującą się po prawej stronie operatora. Dzięki zapisowi $i += 10 wartość zmiennej $i zostanie zwiększona o 10. Warto wspomnieć o możliwości skrótowego zapisu takiej operacji:

echo $i += 10; 


Znaczy to samo, co:

$i += 10;
echo $i; 


Nic nie stoi na przeszkodzie zastosowania innych operatorów arytmetycznych w połączeniu z operatorem przypisania (o operatorach arytmetycznych nieco dalej):

<?
  $i = 10;
  echo $i *= 10; // wyświetli 100
?>


Warto w tym momencie zaprezentować przykłady nieco bardziej skomplikowanych możliwości zastosowania operatorów, które także są jak najbardziej prawidłowe. Np.:

<?  
  $i = 10;
  echo $a = ($i *= 10) + 5;
?>


Przeanalizujmy działanie takiego kodu. W pierwszej linii zadeklarowaliśmy zmienną $i, która posiada wartość 10. W drugiej linii zadeklarowaliśmy zmienną $a do której przypisaliśmy wynik mnożenia wartości zmiennej $i przez 10. Do tego wszystkiego dodaliśmy 5, a całość została wyświetlona przy pomocy instrukcji echo. W wyniku takiego działania zmienna $i będzie posiadać wartość 100, a $a ? 105.

Operatory arytmetyczne


Operatory arytmetyczne służą dokonywania prostych operacji znanych Ci zapewne ze szkoły podstawowej (dodawanie, odejmowanie, mnożenie, dzielenie). Lista operatorów arytmentycznych zawarta została w tabeli 2.

Tabela 2. Lista operatorów arytmetycznych
Przykład        Opis
$a + $b        Dodawanie wartości zmiennych $a i $b
$a - $b        Odejmowanie wartości zmiennych $a i $b
$a * $b        Mnożenie wartości zmiennych $a i $b
$a / $b        Dzielenie wartości zmiennych $a i $b
$a % $b        Reszta z dzielenia zmiennych $a i $b


Należy jedynie wyjaśnić sprawę dzielenia. Domyślny operator dzielenia (/) zwraca wynik w postaci liczby zmiennoprzecinkowej (float). Np.:

echo 5 / 2; // wyświetli 2.5


Zmiennoprzecinkowy wynik dzielenia zawsze można zaokrąglić stosując funkcje PHP: round(), floor() oraz ceil().

Zaokrąglanie


W PHP za zaokrąglanie liczb odpowiadają trzy funkcje. Funkcja floor() zaokrągla ułamki w dół; ceil() zaokrągla ułamki w górę. Oto kilka przykładów użycia tych funkcji:

  echo 'Floor: 3.5: ' . floor(3.5) . '<br>'; // zwróci 3
  echo 'Ceil: 3.5: ' . ceil(3.5) . '<br>'; // zwróci 4
  echo 'Floor: 3.5667 ' . floor(3.5667) . '<br>'; // zwróci 3
  echo 'Ceil: 3.9 ' . ceil(3.9) . '<br>'; // zwróci 4


Jeżeli chodzi o funkcję round() to do dołu lub do góry, w zależności od liczby jaka została owej funkcji przekazana. Jeżeli jednak podamy funkcji liczbę 3.5 to zostanie ona zaokrąglona w gorę:

  echo 'Round(3.5) : ' . round(3.5) . '<br>'; // zwróci 4
  echo 'Round(3.6) : ' . round(3.4) . '<br>'; // zwróci 3


Do funkcji round() możemy przypisać drugi parametr, który jest opcjonalny, a oznacza dokładność zaokrąglania. Spójrz na taki kod:

echo round(2.56777676, 3)


Rezultat działania takiego skryptu to 2.568.

Operatory porównania


Jak łatwo się domyśleć, operatory porównania służą porównywaniu wartości znajdujących się po obu stronach owego operatora. Np. poniższa instrukcja zawsze wyświetli cyfrę 1:

  echo 2 == 2;


Operator == służy sprawdzaniu (tak samo jak w C i innych językach) czy dwie wartości są sobie równe. Ponieważ w tym wypadku porównujemy dwie liczby 2, działanie takiego operatora zwróci true. Musisz wiedzieć, że wartość true jest równe liczbie 1, a false ? 0.

Dlatego też, jeżeli warunek zostanie spełniony (true) to w przeglądarce zostanie wyświetlona cyfra 1. Tabela 3. zawiera pełną listę operatorów porównania.

Tabela 3. Lista operatorów porównania
Przykład        Opis
$a == $b        Zwraca true jeżeli $a jest równe $b
$a === $b        Zwraca true jeżeli $a jest identyczne z $b (obie zmienne są tego samego typu). 
$a != $b        Zwraca true jeżeli $a jest różne od $b
$a <> $b        Zwraca true jeżeli $a jest różne od $b
$a !== $b        Zwraca true jeżeli $a nie jest identyczne z $b
$a > $b        Zwraca true jeżeli $a jest większe od $b
$a < $b        Zwraca true jeżeli $a jest mniejsze od $b
$a >= $b        Zwraca true jeżeli $a jest większe lub równe $b
$a <= $b        Zwraca true jeżeli $a jest mniejsze lub równe $b


Operatory porównywania są często wykorzystywane w połączeniu z instrukcjami warunkowymi, ale o tym będziemy mówić w dalszej części rozdziału.

Chciałem jeszcze wspomnieć o operatorze === i o identyczności typów. Sprawdźmy, czym ów operator różni się od operatora porównania:

  echo 2 == '2';
  echo 2 === '2';


Powyższe dwie instrukcje porównują dwie wartości. Zwróć uwagę, że druga wartość jest zapisana w apostrofach, czyli jest łańcuchem tekstowym. Operator == mimo tego w tym przypadku zwróci wartość true (PHP spróbuje w tym momencie przekonwertować łańcuch na liczbę i wtedy dopiero porównywać dane).

Operator === porównuje także typy danych. Skoro więc jedna wartość jest wartością liczbową, a druga ? łańcuchową ? taka konstrukcja zwróci false.

Operatory logiczne


Operatory logiczne są używane podczas analizy wyrażeń logicznych. Lista operatorów logicznych została zawarta w tabeli 4.

Tabela 4. Lista operatorów logicznych
Przykład                                        Opis
$a and $b (lub $a && $b)        Zwraca true jeżeli zarówno $a jak i $b posiadają wartość true. 
$a or $b (lub $a || $b)        Zwraca true jeżeli $a lub $b posiadają wartość true. 
! $a                                        Zwraca true jeżeli $a nie jest true. 


Być może nie widzisz sensu stosowania operatorów logicznych, lecz często stosuje się je w połączeniu z instrukcjami warunkowymi (o tym dalej) oraz funkcjami.

Operatory wykonania polecenia systemowego


Od razu zaznaczam, że ten operator może nie zadziałać na niektórych serwerach, na których administrator włączył tryb safe_mode lub zablokował funkcje shell_exec(). Operator wykonania polecenia systemowego (bo jest właściwie jeden) umożliwia uruchamianie zewnętrznych aplikacji systemu lub wykonywanie poleceń systemowych. Polecenia systemowe muszą być ograniczone apostrofem wstecznym (`) a rezultat takiego polecenia może być od razu wyświetlony lub przypisany do zmiennej.

Przykładowo, korzystając z systemu Windows możemy wysłać ping do jakiegoś serwera:

<?
  echo `ping www.4programmers.net`;
?>


Rezultatem wykonania takiego polecenia na systemie Windows będzie pojawienie się takiego lub podobnego tekstu, zwróconego przez program:

Badanie 4programmers.net [217.11.138.50] z użyciem 32 bajtów danych:
 
Odpowiedź? z 217.11.138.50: bajtów=32 czas=33ms TTL=57
Odpowiedź? z 217.11.138.50: bajtów=32 czas=34ms TTL=57
Odpowiedź? z 217.11.138.50: bajtów=32 czas=209ms TTL=57
Odpowiedź? z 217.11.138.50: bajtów=32 czas=737ms TTL=57
 
Statystyka badania ping dla 217.11.138.50:
    Pakiety: Wysłane = 4, Odebrane = 4, Utracone = 0 (0% straty),
Szacunkowy czas błądzenia pakietu w milisekundach:
    Minimum = 33 ms, Maksimum = 737 ms, Czas ˜średni = 253 ms


Należy zwrócić uwagę na to, iż PHP jest niezależny od platformy systemowej, więc skrypty można uruchomić zarówno na systemie Windows jak i UNIX. Należy zwrócić uwagę na to, że wiele poleceń dostępnych na system UNIX nie funkcjonuje w systemie Windows. Przykładowo, poniższy skrypt nie zostanie prawidłowo wykonany na systemie Windows:

<?  
  $a = `ls -al`;
  echo $a;
?>


Operatory kontroli błędów


PHP obecnie obsługuje jeden operator kontroli błędów. Jest to znak małpy (@) który postawiony przed jakimkolwiek wyrażeniem PHP spowoduje, iż ewentualny błąd spowodowany przez tę funkcję nie zostanie wyświetlony. Operator kontroli błędów może mieć zastosowanie również przed nazwami zmiennych ? np.:

echo @$zmienna; 


Operatory bitowe


Ostatnia grupa operatorów PHP, to operatory operujące na liczbach. Konkretniej mówiąc działają one na binarnej reprezentacji liczb całkowitych, ale również na ciągach. Tabela 5. zawiera listę operatorów bitowych dostępnych w PHP.

Tabela 5. Lista operatorów bitowych PHP
Przykład        Opis
$a & $b        Mnożenie bitowe. Bit wynikowy jest równy 1 jeżeli obydwa bity składowe są równe 1.
$a | $b        Sumowanie bitowe. Bit wynikowy jest równy 1 jeżeli jeden z bitów składowych jest równy 1. 
$a ^ $b        Dany bit wynikowy jest równy 1 wtedy, gdy jeden z bitów składowych jest równy 1, a drugi 0. 
~ $a        Bity w zmiennej $a mające wartość 0 otrzymują 1 i na odwrót.
$a << $b        Przesuwa bity w zmiennej $a o $b kroków w lewo.
$a >> $b        Przesuwa bity w zmiennej $a o $b kroków w prawo. 


Nie będę rozwlekał tematu operowania na bitach, gdyż wymaga to znajomości przeliczania systemów liczbowych z dwójkowego na dziesiętny i szesnastkowy.

Priorytety operatorów


Podczas programowania w PHP, przy pomocy nawiasów można zmieniać priorytety operatorów, według działań arytmetyki. Przykładowo 2 + 2 * 2 zwróci 6, gdyż operator mnożenia (*) ma większy priorytet. Jednak już po dodaniu nawiasów, wynik takiego działania może wynosić 8: (2 + 2) * 2.

Operatory and, or pomimo, iż działają prawie tak samo jak && i || mają niższy priorytet wykonywania.

Instrukcje warunkowe


Przejdźmy teraz do bardziej zaawansowanego elementu języka, a mianowicie do instrukcji warunkowych, czyli struktur konstruujących działanie programu. Dzięki instrukcjom warunkowym, możemy ustalić kolejność wykonywania aplikacji, w zależności od jej stanu.

Przykładowo, jeżeli użytkownik podał w formularzu na stronie WWW prawidłowe hasło to można przejść do dalszego wykonywania programu. Jeżeli nie ? dalszy dostęp do aplikacji jest blokowany. To właśnie jest realizowane przy pomocy instrukcji warunkowych.

Instrukcja if


Podstawową instrukcją warunkową jest if, która wykonuje dane działania w zależności, do tego, czy podany warunek zostanie spełniony. Instrukcja if posiada taką konstrukcję:

if (warunek) instrukcja;


Jak wspomniałem wcześniej, wraz z instrukcjami warunkowymi, bardzo często wykorzystywane są operatory logiczne oraz porównania:

<?
$var = true;
if ($var) echo 'Zmienna $var posiada wartość true';
?>


Po uruchomieniu takiego programu, przeglądarka wyświetli napis, gdyż taki warunek będzie spełniany zawsze, ponieważ na starcie programu przypisujemy zmiennej $var wartość true. Ten skrypt równie dobrze mógłby wyglądać tak:

<?
$var = true;
if ($var == true) echo 'Zmienna $var posiada wartość true';
?>


Zwracaj uwagę na operator, jakiego używasz w danej sytuacji. Bardzo często operator przypisania (=) stosowany jest w kontekście porównania dwóch wartości, a za to odpowiada operator porównania (==). Jest to bardzo często przyczyną błędów w programie.
Często zachodzi konieczność wykonania jakiegoś kodu, jeżeli warunek posiada wartość fałszywą. W takim wypadku możemy skorzystać z dodatkowego operatora przeczenia (!):

<?
$var = true;
// poniższy warunek nie zostanie nigdy spełniony
if (!$var) echo 'Zmienna $var posiada wartość false';
?>


W podobny sposób można korzystać z pozostałych operatorów porównania:

<?
$i  = rand(1, 100);
if ( $i == 10 ) echo 'Moje gratulacje! Trafiłeś w dziesiątkę!';
?> 


Funkcja rand() losuje liczbę z przedziału od 1 do 100 i zwraca wynik do zmiennej $i. W kolejnej instrukcji następuje sprawdzenie, czy wylosowaną liczbą jest 10. Jeżeli wywołasz funkcję rand() bez podania parametrów, funkcja wylosuje liczbę z przedziału od 1 do N. N jest największą liczbą, jaka może zostać wylosowana. Żeby ją poznać, skorzystaj z funkcji mt_getrandmax():

<?
echo mt_getrandmax(); // wyświetli np. 2147483647
?>


Instrukcja warunkowa może posiadać kilka warunków spełnienia. W takich wypadkach należy skorzystać z operatorów logicznych ? np.:

<?
$prawda = true;
$i = rand(1, 100);
if ( $i == 10 && $prawda ) echo 'Warunek spełniony';
?>


W powyższym przypadku warunek zostanie spełniony, jeżeli zmienna $i będzie posiadała wartość 10, a zmienna $prawda będzie miała wartość true.

Blok instrukcji


Podobnie jak w języku C, bloki instrukcji mogą być zawarte pomiędzy znaki { i }. Powiedzmy, że po spełnieniu warunku chcesz, aby program wyświetlił napis oraz dodatkowo ? zmienił wartość zmiennej. Możesz napisać tak:

<?
$prawda = false;
if ( $prawda )
  echo 'Warunek spełniony';
  $napis = 'Wszystko OK';
 
echo $napis;
?>


Zgodnie z powyższym napisem, warunek nie powinien być spełniany nigdy ? wartość zmiennej $prawda to false. Tymczasem po uruchomieniu takiego skryptu, zobaczysz, że przeglądarka zawsze wyświetla napis Wszystko OK. Nie chcemy, aby tak się działo, ponieważ warunek nie został spełniony. Rozwiązaniem problemu, będzie umieszczenie instrukcji w bloku:

<?
$prawda = false;
if ( $prawda )
{
    echo 'Warunek spełniony';
    $napis = 'Wszystko OK';
}
echo $napis;
?>


Teraz skrypt nie będzie już wypisywał tekstu, gdyż warunek nie został spełniony (zmienna $napis nie została zadeklarowana). Klamer { i } używamy wtedy, gdy do wykonania mamy wiele instrukcji. Ze względu na czytelność kodu zaleca się używania klamer nawet, gdy mamy do czynienia z jedną instrukcją:

<?
  $prawda = true;
 
  if ( $prawda )
  {
      echo 'Warunek spełniony!';
 
      $i = rand(1, 10);
 
      if ( $i == 10 )
      {
          echo 'Wylosowano 10';
      }
  }
 
?>


Klamry { i } spełniają taką samą rolę jak słowa kluczowe begin i end w języku Pascal, czy Delphi.

Mimo, iż PHP nie narzuca żadnego stylu kodowania, czyli formatowania kodu, możesz spotkać się ze specyficznym stylem zapisywania instrukcji, które stosuje w tym artykule. Bloki instrukcji, spacje, poczwórne wcięcia w kodzie ? to wszystko ma na celu zwiększenie przejrzystości kodu. Poprzedni skrypt, równie dobrze mógłbym zapisać w ten sposób:

<?
$prawda = true;
if ($prawda) {
  echo 'Warunek spełniony!';
 
  $i=rand(1, 10);
  if ( $i == 10 )
          echo 'Wylosowano 10';
}
?>


Zastanów się jednak, który wariant jest bardziej czytelny dla Ciebie!

Instrukcja else


Dobrze, wiesz już, do czego służy instrukcja if. Często będziesz zmuszony do wyświetlania jakiegoś komunikatu, czy podjęcia jakiejś reakcji, jeżeli warunek nie zostanie spełniony. W takim wypadku mógłbyś użyć drugiej instrukcji if:

<?
  $prawda = true;
 
  if ( $prawda ) 
  {
      echo 'Prawda';
  }   
  if ( !$prawda ) 
  {
      echo 'Fałsz';
  } 
?>


Prawie wszystkie języki programowania, w tym PHP, udostępniają alternatywę powyższego rozwiązania ? instrukcję else. Kod znajdujący się po instrukcji else zostaje wykonany, jeżeli instrukcja if nie zostanie spełniona. Powyższy kod, można więc zastąpić poniższym:

<?
  $prawda = false;
 
  if ( $prawda )
  {
      echo 'Prawda';
  }
  else
  {
      echo 'Fałsz';
  }
?>


Instrukcja elseif


Instrukcja elseif służy do badania dodatkowych warunków jeżeli poprzedni warunek if nie został spełniony. Każda instrukcja if może zawierać dowolną ilość instrukcji elseif, ale tylko jedną instrukcję else:

<?
  $i = rand(1, 100);
 
  if ( $i == 10 )
  {
      echo 'Wylosowano 10. Gratulacje!';
  }
  elseif ( $i == 50 )
  {
      echo 'Wylosowano 50. Tak sobie...';
  }
  elseif ( $i == 70 )
  {
      echo 'Wylosowano 70. Kiepsko.';
  }
  else
  {
      echo 'Nie wiem co wylosowano';
  }
?>


W pierwszym wersie następuje przypisanie do zmiennej $i, wylosowanej liczby. Kolejne warunki sprawdzają, czy wylosowaną liczbą nie jest 10, 50 lub 70. Jeżeli żaden z tych warunków nie zostanie spełniony ? wykonany zostanie kod z instrukcji else.

W PHP zamiast elseif możesz napisać else if ? wynik działania tych instrukcji jest identyczny.  

Konstrukcja if..endif


Alternatywą w stosunku do używania klamer w połączeniu z instrukcjami if/else/elseif jest konstrukcja if..endif. Stosując ową konstrukcję, poprzedni skrypt można by było zapisać w taki sposób:


<?
  $i = rand(1, 100);
 
  if ( $i == 10 ):
 
      echo 'Wylosowano 10. Gratulacje!';
 
  elseif ( $i == 50 ):
 
      echo 'Wylosowano 50. Tak sobie...';
 
  elseif ( $i == 70 ):
 
      echo 'Wylosowano 70. Kiepsko.';
 
  else:
 
      echo 'Nie wiem co wylosowano';
 
  endif;
?>


Zwróć uwagę na słowo kluczowe endif, które oznacza zakończenie instrukcji. Dodatkowo po instrukcji if/else/elseif znajduje się znak dwukropka! Mimo iż taka konstrukcja jest dopuszczalna, to nie jest zbyt często stosowana.

Operator trójoperandowy


Konstrukcja tej instrukcji może wydać Ci się dziwna, lecz w gruncie rzeczy jest ona bardzo użyteczna i często stosowana. Można powiedzieć, że jest to skrócona wersja instrukcji if. Można jej używać w ten sposób:

<?
  $wakacje = true;
 
  echo ( $wakacje ? 'Lato!' : 'Eh... praca' );
?>


Kod realizujący takie samo zadanie, z użyciem instrukcji if wyglądałby następująco:

<?
  $wakacje = true;
 
  if ( $wakacje )
  {
      echo 'Lato!';
  }
  else
  {
     echo 'Eh... praca';
  }
?>


Operator trójoperandowy można stosować w prostych przypadkach, gdyż jego konstrukcja jest nieco ograniczona i jeżeli warunek zostanie spełniony, tylko jedna instrukcja może być wykonana. Konstrukcja tego operatora jest następująca:

warunek ? (instrukcja spełniona) : (instrukcja nie spełniona)

 
Jeżeli warunek zostanie spełniony, możesz równie dobrze przypisać jakąś wartość do zmiennej, czy dokonać innych operacji:

<?
  $wakacje = true;
 
  ( $wakacje ? $text = 'Lato!' : $text = 'Eh... praca!' );
 
  echo $text;
?>


Instrukcja switch


Instrukcja switch używana jest przeważnie w przypadkach, gdy mamy do czynienia z wyliczeniem wielu możliwych działań w zależności od uzyskanej wartości. Stosuje się ją w przypadkach, które wymagałyby wielu instrukcji if.

Budowa instrukcji switch jest następująca:

switch (warunek)
{
  case wartość1:
  instrukcje;
  break;
 
  case wartość2:
  instrukcje;
  break;
 
  default:
  instrukcje;
}


 W poniższym przykładzie, w zmiennej $lang określono język (pl). Instrukcja switch na podstawie tej wartości przypisuje zmiennej $hello komunikat w wybranym języku:

<?
  $lang = 'pl';
 
  switch ( $lang )
  {
      case 'pl':
      $hello = 'Witaj!';
      break;
 
      case 'en':
      $hello = 'Welcome!';
      break;
 
      case 'de':
      $hello = 'Willkommen!';
      break;
 
      case 'fr':
      $hello = 'Bienvenue!';
      break;
 
      default:
      $hello = 'Witaj!';
  }
 
  echo $hello;
?>


Po uruchomieniu takiego skryptu przeglądarka wyświetli napis Witaj, ponieważ zmienna $lang posiada wartość pl. Wartość tej zmiennej sprawdzana jest przez instrukcję case, która wykonuje w takim wypadku stosowane operacje, czyli przypisanie wartości do zmiennej $hello. Po instrukcjach w bloku case, musi znaleźć się polecenie break, które kończy działanie całej instrukcji warunkowej.

Po usunięciu poleceń break, z ciała instrukcji case, program nie zostanie zatrzymany, a kolejne wyrażenia będą wykonywane. Spowoduje to przypisanie do zmiennej $hello kolejnych wartości Welcome!, Willkommen!, Bienvenue, a na końcu ? Witaj!. Pominięcie polecenia break w instrukcji case jest dość powszechnym błędem początkujących programistów, co skutkuje nieprawidłowym działaniem programu.
Klauzula default, znajdująca się na końcu instrukcji switch może zawierać kod, który zostanie wykonany w razie, gdy żaden z warunków case nie zostanie spełniony.

Pętle


Kolejnym elementem, który mam zamiar omówić są pętle. Służą one do wielokrotnego wykonywania tego samego kodu. Dzięki pętlom możesz w prosty sposób wyświetlić ten sam tekst, ale w gruncie rzeczy mogą posłużyć do bardziej złożonych operacji, wykonywania algorytmów itp.
PHP daje możliwość wykorzystania czterech rodzajów pętli ? każda z nich posiada inną charakterystykę. Ilość iteracji pętli (wykonania) może być ustalona z góry lub też zależeć od spełnionego warunku.

Przykładowo pętla może przez cały czas losować liczbę z zakresu od 1 do 100, dopóki nie zostanie wylosowana liczba 50.

Pętla while


Pętla while jest najprostszą pętlą oferowaną w PHP. Przed wykonaniem sprawdza warunek zakończenia i jeżeli zostaje on spełniony ? nie wykonuje żadnych instrukcji. Jeżeli warunek nie zostanie spełniony wykonuje instrukcje z ciała pętli do momentu spełnienia warunku. Oto budowa pętli while:

while (watunek)
{
   instrukcje;
}


Napiszmy na sam początek program, który ma zadanie losować liczbę z zakresu od 1 do 100 dopóki nie wylosuje liczby 50. Na końcu działania pętli wyświetlimy licznik z ilością prób, które podjął program do osiągnięcia tego rezultatu. Aplikacja, o której mowa, napisana z użyciem pętli while, została przedstawiona na listingu 1.

Listing 1. Losowanie liczby przy użyciu pętli while
<?
  $i = 0; // deklarujemy zmienna (licznik)
 
  while ( $rand != 50 ) // wykonuj dopóki zmienna $rand nie będzie równać się 50
  {
      $rand = rand(1, 100);
      ++$i; // zwiększ licznik prób
  }
 
  echo "Wylosowałem liczbę 50 po $i próbach!";
 
?>


Przeanalizujmy program od końca. Na samym końcu widzimy instrukcję echo która wyświetla komunikat o ilości prób wylosowania liczby 50. Zmienna $i to licznik prób ? na samym początku działania programu nadajemy jej wartość 0. Warunkiem zakończenia pętli jest wylosowanie liczby 50, stąd warunek $rand != 50 który można przetłumaczyć: "wykonuj dalej jeżeli wartością zmiennej $rand nie jest 50". W ciele pętli użyłem operatora inkrementacji w celu zwiększenia wartości zmiennej $i.

Jeżeli Twoje PHP ma ustawioną opcję pokazywania ostrzeżeń, zapewne podczas działania tego programu przeglądarka wyświetli napis: Notice: Undefined variable: rand. PHP próbuje nam przekazać, że zmienna $rand nie została nigdzie zainicjowana, a my próbujemy odwołać się do niej przy pierwszej iteracji pętli. Rozwiązaniem może być dodanie na samym początku skryptu, linii:

  $rand = 0;


Innym rozwiązaniem jest wyłączanie powiadamiania o ostrzeżeniach. Realizuje to funkcja error_reporting(). Na samym początku skryptu możesz więc dodać następującą linię:

  error_reporting(E_ERROR & ~E_NOTICE);


Mówi ona o tym, że chcemy dostawać informację o błędach, ale bez wskazówek (ang. notice).

Warunek zakończenia pętli może być bardziej "skomplikowany", tzn. można używać operatorów porównania oraz operatorów logicznych. Na listingu 2. znajduje się poprawiony kod, który sprawdza, czy wylosowaną liczbą nie jest 50 lub 70.

Listing 2. Losowanie liczby przy użyciu pętli while
<?
  $i = 0; // deklarujemy zmienna (licznik)
  $rand = 0;
 
  while ( $rand != 50 && $rand != 70 ) // wykonuj dopóki zmienna $rand nie będzie równać się 50
  {
      $rand = rand(1, 100);
      ++$i; // zwiększ licznik prób
  }
 
  echo "Wylosowałem liczbę $rand po $i próbach!";
 
?>


Pętla do..while


Pętla do..while jest bardzo podobna do pętli while. W zasadzie jedyną różnicą jest fakt, iż warunek zakończenia pętli sprawdzany jest na końcu a nie na początku jak to ma miejsce przy pętli while. Oznacza to, że pętla zawsze, zostanie wykonana, co najmniej raz. Spójrz na poniższy przykład:

<?
  $bool = false;
 
  do
  {
      echo 'Witaj!';
  }
  while ($bool);
?>


Zmiennej $bool nadajemy wartość false, natomiast w ramach tego co napisaliśmy warunkiem wykonywania pętli jest posiadanie przez zmienną wartości true. Mimo tego po uruchomieniu skryptu przeglądarka wyświetli napis Witaj!. Gdybyśmy zamiast pętli do..while użyli while, skrypt nie zwróciłby żadnego napisu.

Ponieważ zapewne wielu Czytelników programowało wcześniej w języku Pascal, warto wspomnieć, iż pętla do..while jest odpowiednikiem pętli repeat..until w języku Pascal.  

Pętla for


Pętla for zasadniczo różni się od wspomnianych wcześniej pętli. W pierwszym wierszu pętli znajdują się wszystkie wyrażenia kontrolujące:

for (wyrażenie1; wyrażenie2; wyrażenie3) 
{
instrukcje;
}


Przed rozpoczęciem wykonywania pętli, wykonywane jest wyrażenie1. Zazwyczaj ma ono na celu zainicjowanie zmiennej kontrolnej przebieg całej pętli. Wyrażenie2 wykonywane jest przy każdej iteracji pętli ? jeżeli wyrażenie ma wartość true, działanie jest kontynuowane. Oto przykład działania pętli for ? dziesięciokrotne wypisywanie jednego napisu:

<?
  for ( $i = 1; $i <= 10; $i++ )
  {
      echo "Napis nr $i<br>";
  }
?>


W wyniku działania takiego skryptu, przeglądarka wyświetli tekst:

Napis nr 1
Napis nr 2
Napis nr 3
Napis nr 4
Napis nr 5
Napis nr 6
Napis nr 7
Napis nr 8
Napis nr 9
Napis nr 10


Pierwsze wyrażenie z pętli inicjuje zmienną $i (nadaje jej wartość 1). W tym momencie zaczyna się wykonywanie ciała pętli, czyli wypisanie pierwszego tekstu na ekranie. Druga iteracja sprawdza warunek zakończenia. Warunkiem zakończenia jest osiągnięcie przez zmienną $i wartości większej niż 10. Jeżeli warunek nie jest spełniony pętla wykonuje wyrażenie3, czyli zwiększenie wartości zmiennej $i o 1.
Działanie w wyrażeniu trzecim niekoniecznie musi zwiększać wartość zmiennej o 1. Równie dobrze taka pętla może wyglądać w ten sposób:

<?
  for ( $i = 1; $i <= 10; $i += 2 )
  {
      echo "Napis nr $i<br>";
  }
?>


Dzięki temu realizujemy "przeskok" iteracji o dwa "oczka". W rezultacie tego wykonanych zostanie jedynie 5 iteracji pętli:

Napis nr 1
Napis nr 3
Napis nr 5
Napis nr 7
Napis nr 9


Pętla for w języku PHP (podobnie zresztą jak w C) daje duże możliwości i jest bardzo elastyczna. Spójrz na poniższy przykład:

<?
  $j = 0;
 
  for ( $i = 1; $i <= 10; $j++, $i += 2 )
  {
      echo "Napis nr $i<br>";
  }
 
  echo "Wystąpiło $j iteracji...";
?>


Oprócz zwiększania wartości zmiennej $i o 2, zwiększamy także wartość zmiennej $j o 1. Taką operację równie dobrze moglibyśmy umieścić w ciele pętli:

<?
  $j = 0;
 
  for ( $i = 1; $i <= 10; $i += 2 )
  {
      $j++;
      echo "Napis nr $i<br>";
  }
 
  echo "Wystąpiło $j iteracji...";
?>


Jeszcze jeden przykład. Wszystkie instrukcje z ciała pętli mogą być przeniesione z ciała do warunku drugiego:

<?
  $j = 0;
 
  for ( $i = 1; $i <= 10; print "Napis nr $i<br>", $j++, $i += 2 );
 
  echo "Wystąpiło $j iteracji...";
?>


Zauważ jednak, że konieczne było użycie instrukcji print, a nie echo. Ma to związek ze specyfiką obojga instrukcji, o których wspominałem na początku tego artykułu.

Pętle forever


Specyfika pętli for pozwala nam na opuszczenie nawet wszystkich parametrów, co owocuje powstaniem tzw. pętli forever:


for (;;)
{
}


Taka pętla będzie wykonywana w nieskończoność. Przytoczmy ponownie przykład z losowaniem:

<?
  $i = 0;
 
  for (;;)
  {
     ++$i;
 
     if ( rand(1, 100) == 50 )
     {
         break;
     }
  }
 
  echo "Liczba wylosowana po $i próbach";
?>


W tym programie pętla będzie wykonywana dopóty dopóki nie zostanie wylosowana liczba 50. Instrukcja break, w połączeniu z pętlami powoduje wyjście z ciała (zakończenie działania pętli).  

O instrukcjach break oraz continue opowiem nieco dalej.
W pętli for można pominąć jedynie warunek zakończenia, dzięki czemu jesteśmy w stanie ukrócić poprzedni program:

<?
  for ( $i = 1;; $i++)
  {
     if ( rand(1, 100) == 50 )
     {
         break;
     }
  }
 
  echo "Liczba wylosowana po $i próbach";
?>


Skoro mowa o pętli forever, to należałoby wspomnieć o tym, że pętla while także posiada taką możliwość ? oto przykład:

<?
  $i = 0;
 
  while (1)
  {
     if ( ++$i == 10 )
     {
         echo 'Kończymy!';
         break;
     }
  }
?>


Pętla for działająca w drugą stronę


Jeżeli programowałeś wcześniej w języku Pascal, to wiesz, że i tam istnieje pętla for. Jeżeli chcemy, aby zmienna pomocnicza zmniejszała swoją wartość, musimy zastosować słowo kluczowe downto. W PHP sytuacja wygląda nieco inaczej ? tutaj wystarczy zastosować operator dekrementacji:

<?
  for ( $i = 10; $i > 0; $i-- )
  {
      echo "Napis nr $i<br>";
  }
?>


Zwróć uwagę, że wartość początkowa, pomocniczej zmiennej $i to 10. Za każdą iteracją tej pętli wartość ta podlega zmniejszeniu.

Pętla foreach


Pętla foreach została włączona do PHP dopiero w wersji 4.0. Operuje ona jedynie na tablicach dlatego też na razie nie będę wyjaśniał jej działania.
 

Instrukcje continue i break


Instrukcja break służy do natychmiastowego zakończenia działania pętli. Jak zapewne już zauważyłeś działa ona także w połączeniu z instrukcją switch. Instrukcja break obsługuje dodatkowy parametr, który mówi ile struktur ma zostać zakończonych w danym momencie (może się bowiem zdarzyć, że np. instrukcja switch zostanie umieszczona w pętli). Spójrz na poniższy kod:

<?
  for ( $i = 1;; $i++)
  {
     switch ( rand(1, 100) )
     {
         case 20:
         echo 'Wylosowano liczbę 20<br>';
         break 1;
 
         case 50:
         echo 'Wylosowano liczbę 50<br>';
         break 2;
     }
  }
 
  echo "<br>Wystąpiło $i iteracji";
 
?>


Jeżeli wylosowaną liczbą jest 20, program wyświetli komunikat, a następnie opuści jedynie instrukcję switch (liczba 1 przy instrukcji mówi o ilości instrukcji, które trzeba opuścić). Przy wylosowaniu liczby 50, nakazujemy aplikacji opuszczenie zarówno instrukcji switch jak i pętli. W rezultacie takiego działania, przeglądarka może wyświetlić np. taki tekst:

Wylosowano liczbę 20
Wylosowano liczbę 20
Wylosowano liczbę 20
Wylosowano liczbę 20
Wylosowano liczbę 50
 
Wystąpiło 197 iteracji


Jeżeli chodzi o instrukcję continue, to jej wystąpienie powoduje do przejścia do kolejnej iteracji, z pominięciem dalszego kodu:

<?
  for ( $i = 1;; $i++)
  {
     $rand = rand(1, 100);
 
     if ( $rand == 50 )
     {
         echo 'Wylosowano liczbę 50<br>';
         continue;
 
         echo 'Ale fajnie, ten napis nigdy się nie pojawi!';
     }
 
     if ( $rand == 20 )
     {
         break;
     }
  }
 
  echo "<br>Wystąpiło $i iteracji";
 
?>


Instrukcja continue, podobnie jak i break obsługuje dodatkowy parametr mówiący ile poziomów zagnieżdżonych pętli dana instrukcja dotyczy. W powyższym skrypcie, po wylosowaniu liczby 50, wyświetlany jest napis, a program przechodzi do następnej iteracji. Pętla kończy działania dopiero po wylosowaniu liczby 20.

Funkcje


Idea programowania proceduralnego zaczęła się pojawiać wraz z bardziej zaawansowanymi programami. Tradycyjny moduł projektowania nie sprawdzał się dobrze, gdy programy zaczęły być bardziej skomplikowane ? wówczas ich konserwacja, naprawianie błędów było niezwykle trudne.
 
Ktoś mądry wymyślił wtedy, że można by było program dzielić na mniejsze części ? tzw. procedury. Przykładowo, jeżeli mamy kod, który wyświetla pewien komunikat i kończy działanie programu, a ów kod jest używany wiele razy w programie to należałoby go dublować kilkakrotnie. Powoduje to nie tylko zwiększenie objętości kodu, ale również większe narażenie na błędy. Bo co jeżeli w tym małym fragmencie, który jest zdublowany wiele razy, wystąpi błąd? Należałoby wówczas przeszukiwać cały kod i w każdym miejscu poprawiać usterkę.
Teraz, w nowoczesnych językach programowania można pewien fragment kodu umieścić w procedurze i ? za każdym razem kiedy zajdzie potrzeba jego wykonania ? wywołać procedurę!

W językach takich jak C, czy PHP nie istnieją procedury, a funkcję. Podczas czytania tego podręcznika stosowałeś już funkcję wbudowane w PHP ? m.in. rand(). Owa funkcja realizująca proces losowania liczb może przyjmować parametry, które należy podać w nawiasach. Każdy parametr należy oddzielić znakiem przecinka. Język PHP pozwala na definiowanie własnych funkcji, z użyciem słowa kluczowego function.
Każda funkcja musi posiadać nazwę ? parametry są opcjonalne:

function About() { }


Kod funkcji należy wpisać pomiędzy klamrami. Nazwy funkcji nie są wrażliwe na wielkość liter, nie możesz więc zadeklarować dwóch funkcji o takiej samej nazwie:

function about() { }
function ABOUT() { } 


Nazwa funkcji nie może rozpoczynać się od cyfry. Może natomiast zawierać polskie znaki, cyfry oraz znak podkreślenia (_).

Parametry funkcji


Funkcja nie musi, ale może posiadać parametry. Deklarując funkcję, nazwy parametrów należy wpisać w nawiasie, oddzielając je przecinkami:

function foo($x, $y) 
{
}


Nie ma ograniczeń, co do liczby parametrów. Napiszmy prosty program, korzystający z funkcji, którego celem będzie przeliczanie stopni Celsjusza na Fahrenheita. Program znajduje się na listingu 3.

Listing 3. Program przeliczający stopnie Celsjusza na Fahrenheita
<?
 
  function Fahrenheit( $Celsius )
  {
      return ( $Celsius * 9/5 + 32 );
  }
 
  $Celcius = 30;
 
  echo "$Celcius stopni Celsjusza to " . Fahrenheit($Celcius) . " stopni Fahrenheita";
 
?>


Funkcje mogą, lecz nie muszą zwracać wyniku. W naszym wypadku funkcja Fahrenheit() pobiera wartość parametru $Celsius i przelicza stopnie na skalę Fahrenheita, by na końcu zwrócić wynik do aplikacji. Za zwrócenie rezultatu działania funkcji, odpowiada instrukcja return, która równa się zakończeniu działania funkcji. Przestrzegam, więc początkujących programistów przed umieszczeniem kodu po poleceniu return! Taki kod nie zostanie nigdy wykonany.

Parametry domyślne


Funkcja rand() nie wymagała parametrów aczkolwiek je akceptowała. My, deklarując funkcję także możemy ustalić parametry domyślne, tzn. takie których podanie nie jest wymagane. Np.:

function Fahrenheit( $Celsius = 20 )
{
    return ( $Celsius * 9/5 + 32 );
}


Jeżeli nie podamy parametru, wywołując funkcję Fahrenheit(), parametrowi $Celsius zostanie nadana wartość 20. Należy zaznaczyć, że jeżeli mamy do czynienia z wieloma parametrami, te domyślne powinny być zgrupowane po prawej stronie. Spójrz na ten kod:

<?
 
 function foo($param1 = 'param1', $param2)
 {
   echo $param1;
 }
 
 foo();
?>


Mamy tu do czynienia z parametrem domyślnym $param1, który znajduje się po lewej stronie. Parametr $param2 nie jest już domyślny, a znajduje się po stronie prawej. Wywołując funkcję foo() nie możemy pominąć parametru pierwszego mim iż jest on domyślny. Wszystko dlatego, że funkcja foo() wymagania podania wartości parametru $param2.

Zmienne lokalne


W funkcjach możesz deklarować zmienne, które widoczne będą jedynie w obrębie tej funkcji (takie zmienne nazywamy zmiennymi lokalnymi). PHP, pamięć dla tych zmiennych rezerwuje w momencie wywołania danej funkcji, a zwalnia w momencie zakończenia działania owej funkcji. Dlatego taki kod nie zostanie wykonany prawidłowo:

<?
 
 function foo()
 {
     $foo = 'Zmienna';
 }
 
 foo();
 echo $foo;
?>


Tj. skrypt można uruchomić, ale z punktu widzenia PHP, zmienna $foo nie jest zadeklarowana. Użyliśmy jej bowiem, jedynie w funkcji foo() ? po zakończeniu jej działania zmienna lokalna została usunięta.

Ponieważ interpreter wykonuje instrukcje od góry do dołu, w PHP3 funkcja musiała być zadeklarowana przed jej wywołaniem. Począwszy od PHP4, takiego wymogu nie ma więc wywołanie funkcji może wyglądać tak:

foo();
 
function foo()
{
} 


Zakres zmiennej


To, co z początku w PHP może wydać się problematyczne to używanie zmiennych globalnych w funkcjach. Normalnie zmienne globalne nie są widoczne dla funkcji ? trzeba jawnie określić, iż planujemy użyć zmiennej globalnej, w danej funkcji. Służy tego słowo kluczowe global:

<?
 
  // deklaracja nowej zmiennej
  $foo = 20;
 
  function foo()
  {
      // użyj zmiennej w funkcji
      global $foo;
      // zmień jej wartość
      $foo = 10;
  }
 
 foo();
 echo $foo; // wyświetli 10
?>


Zmienne globalne to zmienne deklarowane w programie, natomiast zmienne lokalne są deklarowane w funkcjach.

Dzięki instrukcji global jesteśmy w stanie modyfikować wartość zmiennej z poziomu funkcji. Usuń z programu instrukcję global, doprowadzając wygląd funkcji do takiej postaci:

  function foo()
  {
      // zmień jej wartość
      $foo = 10;
  }


Zobacz jaki będzie efekt działania takiego programu. Wartość zmiennej nie ulegnie zmianie ? w funkcji foo() zostanie zadeklarowana nowa zmienna lokalna o tej samej nazwie, co zmienna globalna (jest to możliwe), lecz będą to dwie różne zmienne.

Czas życia zmiennej


Wspomniałem wcześniej iż zmienne lokalne "żyją" jedynie w trakcie działania funkcji. Po jej zakończeniu, zmienna lokalna jest niszczona. Jest to prawda aczkolwiek możemy to zmienić stosując dyrektywę static. Przypatrz się poniższemu skryptowi:

<?
  function foo()
  {
      static $foo = 0;
      return ++$foo;
  }
 
  $foo = foo();
  $foo = foo();
 
  echo $foo;
?>


W funkcji foo() deklarujemy zmienną $foo i przypisujemy jej wartość 0. Klauzula static znajdująca się przez nazwą zmiennej powoduje zachowanie wartości zmiennej nawet po zakończeniu działania funkcji. Funkcja foo() zwraca zinkrementowaną wartość zmiennej $foo ? jeżeli owa funkcja zostanie wykonana dwa razy, zmienna $foo będzie posiadała wartość 2.

Z powyższego skryptu usuń klauzulę static i sprawdź działanie programu.

Funkcje zagnieżdżone


PHP umożliwia deklarowanie funkcji wewnątrz innych funkcji, lecz takie zagnieżdżone funkcje nie mogą być wywoływane bezpośrednio z programu:

<?
 
  function foo()
  {
      function bar()
      {
 
      }
 
      bar(); // wywołanie funkcji
  }
 
  /* funkcja bar() nie będzie dla PHP widoczna */
  bar();
?>


Programowanie strukturalne


Nieco wcześniej, w tym rozdziale wspominaliśmy o programowaniu proceduralnym, które było ułatwieniem podczas pisania programów.

Podział na procedury i funkcje jednak nie wystarczył, gdy programy były coraz dłuższe. Wówczas ktoś wpadł na pomysł, aby części kodu źródłowego podzielić na inne mniejsze pliki. Taką możliwość wprowadzono także w jednej z wcześniejszych wersji Turbo Pascala.
Idee dzielenia kodu na mniejsze pliki nazwano programowaniem strukturalnym.

Dzielenie programu na kilka mniejszych części znacznie ułatwia konserwacje programu oraz projektowanie. Przykładowo, w jednym pliku (nazwanym przykładowo functions.php) mogą znaleźć się funkcje, z których często będziemy korzystać. Następnie skrypt index.php może korzystać ze skryptu functions.php dzięki czemu będziemy mogli wykorzystać funkcje znajdujące się w tym module.  

Moduł to zwykły plik tekstowy zawierający kod języka, czyli inaczej mówiąc ? zwykły skrypt PHP.

Włączenie kodu PHP z innego skryptu realizowane jest przez instrukcję include lub require. Spójrz na listingi 4. oraz 5.

Listing 4. Moduł zawierający funkcję Fahrenheit()
<?
 
  function Fahrenheit( $Celsius )
  {
      return ( $Celsius * 9/5 + 32 );
  }
 
?>


Listing 5. Skrypt włączający moduł 4.php
<?
  /* włączenie skryptu p3.4.php */
  include 'p3.4.php';
 
  $Celcius = 30;
 
  echo "$Celcius stopni Celsjusza to " . Fahrenheit($Celcius) . " stopni Fahrenheita";
 
?>


Listing 4. zawiera funkcję Fahrenheit() którą następnie można wykorzystywać w wielu innych skryptach PHP. Włączenie tego modułu w inny skrypt jest możliwe dzięki instrukcji include.

W PHP zamiast include, możesz użyć instrukcji require. Obydwie instrukcje działają niemalże identycznie. Jedyną różnicą jest obsługa błędów. Jeżeli próbujemy włączyć do skryptu moduł, który nie istnieje (albo jego nazwa się zmieniła), instrukcja include wygeneruje tylko ostrzeżenie. Instrukcja require w takim wypadku pokaże błąd Fatal Error.

Podczas włączania modułu przy pomocy instrukcji require lub include, nazwę owego modułu możesz podać w nawiasach:

include('p3.4.php');


Do włączania modułów do skryptu, służą także instrukcje include_once oraz require_once. Działają one podobnie jak include i require, z tą różnicą że jeżeli plik został już wcześniej dodany do skryptu, nie zostanie dodany ponownie. Spójrz na poniższy kod:

<?
  /* wł?czenie skryptu p3.4.php */
  include 'p3.4.php';
  include 'p3.4.php';
 
  $Celcius = 30;
 
  echo "$Celcius stopni Celsjusza to " . Fahrenheit($Celcius) . " stopni Fahrenheita";
 
?>


Wykonanie takiego skryptu spowoduje wystąpienie błędu Fatal error: Cannot redeclare fahrenheit(). Gdy w miejsce include wstawimy include_once, skrypt zostanie wykonany poprawnie.

Należy zwrócić uwagę na nazwy skryptów włączanych przy pomocy instrukcji include i require. Konkretnie chodzi o wielkość liter na systemach nie rozróżniających wielkości liter ? takich jak Windows:

  include 'P3.4.php'; // wczyta skrypt p3.4.php


Włączanie modułów w ciało funkcji


Jeżeli zastosujemy instrukcję include (lub require) w ciele danej funkcji, to kod z tego modułu zostanie wstawiony w ową funkcję. Należy się liczyć z tym, że kod takiego modułu nie będzie widoczny poza daną funkcję.

Operacje na łańcuchach


PHP udostępnia kilka ciekawych funkcji operujących na łańcuchach, o których istnieniu powinieneś mieć świadomość. W tej części zaprezentuje przykłady użycia tych funkcji, lecz proszę nie mylić tego z wyrażeniami regularnymi.

sprintf


Oto budowa funkcji sprintf (parametry oraz zwracana wartość):

string sprintf ( string format [, mixed args])


Funkcja sprintf() zwraca sformatowany łańcuch tekstowy. Pierwszym parametrem tej funkcji musi być łańcuch, który zawierać będzie znaki poprzedzone znakiem procenta (%). Owe znaki zostaną w trakcie procesu formatowania, zastąpione wartościami z kolejnych parametrów funkcji sprintf() ? np.:

<?
  $imie = 'Adam';
  echo sprintf('Mam na imię %s', $imie);
?>


Taki skrypt wyświetli napis Mam na imię Adam. W miejsce znaków %s, zostanie wstawiona zawartość zmiennej $imie. Parametr %s oznacza, że to miejsce ma zostać zastąpione wartością łańcuchową. Istnieje możliwość, aby w formatowanym łańcuchu umieścić następujące parametry:

  • %% - wstawia znak procenta (%);
  • %d ? wartość typu integer;
  • %f ? wartość typu float;
  • %s ? wartość typu string;
  • %x ? wartość szesnastkowa;
  • %b ? wartość binarna;
  • %c ? pojedynczy znak;

Spójrz na poniższy przykład prezentujący obliczanie procentowej zawartości danej sumy:

<?
  $percentage = 25;
  $value = 120;
 
  echo sprintf('%f%% ze %f złotych to %f zł', $percentage, $value, ( $percentage * $value / 100 ) );
?>


Taki skrypt obliczy procent (określony w zmiennej $percentage) z sumy określonej w zmiennej $value. Przeglądarka może wyświetlić taki tekst:
25.000000% ze 120.000000 złotych to 30.000000 zł

Mimo, iż skrypt działa prawidłowo, wartości zmienno przecinkowe należałoby zaokrąglić do, powiedzmy ? dwóch miejsc po przecinku. Jest to możliwe dzięki takiemu formatowaniu łańcucha:

echo sprintf('%0.2f%% ze %0.2f złotych to %0.2f zł', $percentage, $value, ( $percentage * $value / 100 ) );


W PHP istnieje również instrukcja printf() która działa bardzo podobnie do sprintf(). Jedyną różnicą jest fakt, iż sprintf() to funkcja, która zwraca wartość tekstową, czyli możemy taką wartość przypisać do zmiennej. Instrukcja printf() nie zwraca żadnej wartości ? należy użyć jej w ten sposób:

  printf('%0.2f%% ze %0.2f złotych to %0.2f zł', $percentage, $value, ( $percentage * $value / 100 ) );


strtolower, strtoupper


string strtolower ( string str)
string strtoupper ( string string)


Funkcje strtolower() oraz strtoupper() umożliwiają zmianę wszystkich znaków podanych w łańcuchu na małe lub duże znaki. Zasada użycia jest dość prosta:

<?
  $string = 'php jest super!';
 
  echo strtoupper($string) . '<br>';
  echo strtolower($string);
?>


W wyniku działania takiego skryptu, przeglądarka wyświetli:

PHP JEST SUPER!
php jest super!


Możesz także skorzystać z funkcji ucfirst() która zamienia jedynie pierwszy znak danego łańcucha na duża literę.

PHP udostępnia także funkcję ucwords() która zamienia na wielkie litery jedynie pierwsze znaki danych wyrazów ? np.:

echo ucwords('hello world');  // zwróci Hello World


trim


string trim ( string str [, string charlist])


Funkcja trim() usuwa tzw. "białe" znaki z początku oraz końca łańcucha tekstowego. Pisząc "białe znaki" mam na myśli spacje, znaki nowej linii (\n) lub tabulacje (\t):

<?
  echo trim("   To jest tekst, który zawiera białe znaki...\n    ");
?>


Funkcja trim() posiada drugi, opcjonalny parametr, który określa listę znaków, które zostaną usunięte z początku i końca łańcucha. Możesz, więc użyć funkcji trim() w ten sposób:

 
 echo trim("   To jest tekst, który zawiera białe znaki...\n    ", "\n\t \0");


Domyślnie, funkcja trim() usuwa następujące znaki:

  • " " ? spacja;
  • \t ? znak tabulacji;
  • \n ? znak nowej linii;
  • \r ? powrót karetki;
  • \0 ? pusty bajt;

PHP udostępnia także funkcje ltrim() oraz rtrim() które usuwają kolejno białe znaki z lewej oraz prawej strony łańcucha.

strlen


int strlen ( string str)


strlen() jest przydatną funkcją służącą do określania długości łańcucha podanego w parametrze. Zwracana ona liczbę określającą ilość znaków:

echo strlen('PHP'); // zwróci 3


chr, ord


string chr ( int ascii)
int ord ( string string)

Te dwie proste funkcje służą do operowania na kodach ASCII.
ASCII to skrót od słów American Standard Code for Information Interchange. Jest to zestaw kodów z zakresu od 0 do 127, przyporządkowany przez ANSI, amerykański instytut do spraw standardów. Poszczególnym znakom alfanumerycznym (litery alfabetu angielskiego i cyfry) przyporządkowany jest numer. Np. litera a ma numer 97.

Funkcja ord() zwraca numer znaku podanego w parametrze natomiast funkcja chr() zwraca znak na podstawie numeru podanego w parametrze tej funkcji:

<?
  echo ord('A'); // zwróci 65
  echo chr(65);  // zwróci A
?>


nl2br


string nl2br ( string string)


Funkcja umożliwia zastąpienie znaków nowej linii, znacznikami XHTML -
. Oto przykład użycia:

echo nl2br("Pierwsza linia\nDruga linia");


W powyższym przykładzie, wstawiamy znak nowej linii (\n) w sposób jawny. Możemy jednak fizycznie rozdzielić łańcuch, w ten sposób:

  echo nl2br("Pierwsza linia
              Druga linia");


Efekt będzie taki sam.

str_replace


mixed str_replace ( mixed search, mixed replace, mixed subject [, int &count])


Bardzo użyteczna funkcja str_replace() umożliwia zastępowanie tekstu w łańcuchu, w prosty i szybki sposób. Funkcja posiada trzy parametry, które są wymagane do prawidłowego działania: szukana fraza, nowa fraza oraz jako trzeci parametr ? łańcuch, w którym odbędzie się szukanie. Oto przykład:

<?
   echo str_replace('fajne', 'super', 'PHP jest fajne');
?>


W powyższym skrypcie, słowo fajne zostanie zastąpione przez super, w wyniku czego przeglądarka wyświetli napis: PHP jest super.
 
Począwszy od PHP 5 funkcja str_replace() wyposażona została w nowy, opcjonalny parametr, który poprzez referencję zwraca ilość zastąpionych fraz:

<?
   $text = str_replace('fajne', 'super', 'PHP jest fajne, a użycie MySQL też jest fajne', $counter);
   echo "Nowy tekst: $text; zastąpiono <b>$counter</b> frazy!";
?>


Funkcja str_replace() jest wrażliwa na wielkość liter. W poniższym przykładzie, zastąpiona zostanie tylko jedna fraza, dlatego, że w łańcuchu znajduje się wyraz FAJNE, który jest pisany wielkimi literami:
 
 
 $text = str_replace('fajne', 'super', 'PHP jest FAJNE, a użycie MySQL też jest fajne', $counter);


Lekarstwem na to może być użycie funkcji str_ireplace() która została do PHP włączona dopiero w wersji 5.0. Nie rozróżnia ona wielkości liter; poza tym działa identycznie, co str_replace().

strstr


string strstr ( string haystack, string needle)


Funkcja przeszukuje łańcuch haystack w poszukiwaniu frazy needle. Jeżeli takową znajdzie zwraca część łańcucha począwszy od niej do końca. Przykład:

<?
   echo strstr("[email protected]", "@"); // zwróci @server.com
?>


Funkcja ta jest wrażliwa na wielkość liter. Jeżeli nie chcesz, aby małe/wielkie litery były rozróżniane zastosuj funkcję stristr.

substr


string substr ( string string, int start [, int length])


Funkcja umożliwia wycięcie części z podanego łańcucha (określonego w pierwszym parametrze). Drugi parametr, start określa pozycję, od której rozpocznie się wycinanie. Ostatni, opcjonalny parametr length określa ilość znaków do wycięcia:

<?
   echo substr("Gumisie, Kaczor Donald i Muminki to moje ulubione bajki", 9);
?>


W tym przykładzie funkcja wytnie 9 pierwszych znaków z łańcucha i wyświetli napis Kaczor Donald i Muminki to moje ulubione bajki. Oto jak wyglądałaby ta funkcja, jeżeli chcielibyśmy zostawić jedynie frazę Kaczor Donald i Muminki:

echo substr("Gumisie, Kaczor Donald i Muminki to moje ulubione bajki", 9, 23);


Funkcja substr() akceptuje także parametry ujemne, w przypadkach, gdy chcemy wyciąć tekst znajdujący się na końcu frazy:

   echo substr("Gumisie, Kaczor Donald i Muminki to moje ulubione bajki", -19); // zwróci moje ulubione bajki


strpos


int strpos ( string haystack, string needle [, int offset])


Funkcja strpos() zwraca liczbę typu integer, która określa pozycję frazy needle w łańcuchu haystack. Trzeci, opcjonalny parametr offset umożliwia określenie od którego miejsca w łańcuchu rozpocznie się poszukiwanie. Poniżej przedstawiam przykład sprawdzenia czy w adresie e-mail występuje znak @ :

<?
   if ( strpos("[email protected]", "@") == 0 )
   {
       echo 'Zły adres';
   }
?>


Funkcja zwraca położenie danego znaku (lub łańcucha), ale może to być także liczba 0, która oznacza, iż znak nie został odnaleziony lub znajduje się na pierwszej pozycji w łańcuchu.

Funkcja stripos() działa bardzo podobnie co strpos() z tym, że nie zwraca uwagi na wielkość znaków.

Referencje


Mówiliśmy o zmiennych jako o pojemniku do przechowywania danych. Taka zmienna identyfikowana jest poprzez nazwę. My nie musimy się o nic martwić ? to PHP odpowiada za umieszczenie zawartości zmiennej w odpowiedniej komórce pamięci.

Referencje są sposobem dostępu do wartości zmiennej poprzez różne nazwy. Należy bowiem rozróżnić dwie rzeczy jakimi są: wartość zmiennej oraz nazwa zmiennej. Ta sama wartość może być odczytana poprzez różne nazwy ? to właśnie umożliwia referencja.
Referencję utworzyć można poprzez operator &:

<?
 
  $a = 10;
  $b = &$a;
 
  echo $b;
 
?>


Dzięki temu utworzyliśmy powiązanie zmiennej $b, ze zmienną $a. Należy zaznaczyć, że od tej pory zarówno zmienna $b jak i $a wskazują na to samo miejsce w pamięci, a tym samym ? posiadają tę samą wartość. W powyższym przykładzie instrukcja echo wyświetli wartość 10.

Oto kolejny przykład:

<?
  $a = 10;
  $b = &$a;
 
  $a = 20;
 
  echo $b;
?>


Zauważ, że po utworzeniu referencji, wartość zmiennej $a zostaje zmieniona na 20, a w następnym wierszu wyświetlamy wartość zmiennej $b. Jednak w skutek działania tego skryptu i tak zostanie wyświetlona liczba 20. Wszystko dlatego, że zarówno $a i $b wskazuje na tę samą wartość.

Przekazywanie przez referencje


Przypomnij sobie fragment rozdziału, w którym omawialiśmy budowę funkcji. Do każdej funkcji można było przekazać parametr, na którym funkcja mogła swobodnie operować. Takie przekazywanie nazywa się przekazywaniem przez wartość. Polega to na utworzeniu lokalnej kopii zmiennej do wykorzystania jedynie przez funkcję. Oryginalna wartość zmiennej przekazanej do funkcji, nie zostaje w żaden sposób naruszona. Przykład:

<?
  function foo($value)
  {
     $value = 15;
  }
 
  $a = 10;
  foo($a);
  echo $a;
?>


Na samym początku deklarujemy zmienną $a i przypisujemy jej wartość 10, którą następnie przekazujemy do funkcji foo(). W funkcji modyfikujemy wartość przekazanego parametru, lecz zmienna $a nadal będzie posiadać wartość 10. Wszystko dlatego, że parametr funkcji foo() - $value ? jest jedynie kopią zmiennej $a.

Przekazywanie parametrów przez referencję jest szybsze i mniej "pamięciożerne", gdyż funkcja nie operuje na kopii zmiennej, ale na wartości oryginalnej. Wystarczy umieścić operator & przed nazwą parametru w funkcji foo():

<?
  function foo(&$value)
  {
     $value = 15;
  }
 
  $a = 10;
  foo($a);
  echo $a;
?>


W funkcji foo() następuje zmiana wartości parametru $value. Jako, że parametr $value wskazuje na tę samą wartość, co wartość zmiennej $a, instrukcja echo wyświetli liczbę 15.

Nie należy zapominać, że przekazywanie przez referencję wiąże się z przekazaniem zmiennej (lub instrukcji new ? o tym w dalszej części) ? inne wartości (np. stałe) nie są akceptowane, tak więc poniższe wywołanie zakończy się komunikatem błędu Only variables can be passed by reference:

foo(10); // stała, a nie zmienna


W PHP 5 możliwe jest ustawianie domyślnych wartości dla parametrów funkcji, które mają być przekazane przez referencje.
Usuwanie referencji
Normalnie za niszczenie danej zmiennej w trakcie działania programu, odpowiada funkcja unset():

  $a = 10;
  unset($a);
  echo $a;


W powyższym kodzie, zmienna $a nie będzie już dostępna. Funkcja unset() odpowiada także za niszczenie referencji. Nie usuwa jednak wartości z pamięci, lecz kasuje powiązanie pomiędzy zmiennymi. Oto przykład:

<?
  $a = 10;
  $b = &$a;
 
  $a = 20;
  unset($a);
 
  echo $b;
?>


W tym przykładzie funkcja unset() usuwa powiązanie zmiennej $a z $b, lecz sama wartość nie zostaje usunięta z pamięci. Wciąż, więc można odczytać wartość korzystając z odwołania do zmiennej $b. Taki kod spowoduje wyświetlenie na ekranie liczby 20.

5 komentarzy

bordeux 2008-01-23 08:19

i o klasach :<

Format 2006-12-17 00:23

Szkoda, ze nie opisano foreach. Tylko tej konstrukcji nie znam :P

Grzybu 2008-02-16 17:24

Gdzieś wcięło kilka rozdziałów, o zmiennych i stałych  i początkowe o operatorach. Coś się zchrzaniło.

Mabakay 2004-10-18 16:32

Podziwiam Cie za to, ze chialo Tobie pisac sie az tyle, ale w koncu piszesz ksiazki ;)

MrPascal 2004-10-19 16:04

Książki Pana Adama zawsze były na wysokim poziomie merytorycznym i były bardzo przejrzyste. Pozdrawiam