Kurs PHP. Wstęp do programowania w popularnym języku skryptowym
Celem tego kursu nie jest przekazanie wiedzy encyklopedycznej na temat PHP, ale praktycznych porad, które każdemu pozwolą na tworzenie ciekawych i funkcjonalnych aplikacji. Dlatego na początku powiedzmy tylko, że PHP (akronim rekursywny „PHP: Hypertext Preprocessor”) to język skryptowy wykonywany po stronie serwera (przez co oferuje większe możliwości niż np. JavaScript) o składni podobnej do C/C++, za pomocą którego tworzymy zaawansowane programy wykorzystywane głównie na stronach WWW.
Atutem PHP jest zaś to, że programista nie musi się tutaj przejmować np. lokowaniem pamięci pod zmienne czy konwersją typu. Dodatkowo możliwości PHP można rozszerzyć, instalując na serwerze gotowe moduły lub pisząc własne. Obecnie rozwijana jest wersja 5.x, a rozwój wersji 4.xx (długo współistniejącej z nowszą „piątką”) zatrzymał się w sierpniu 2007 roku na edycji 4.32. Obie wersje różnią się znacznie pod względem zaawansowanych funkcji obsługi baz danych, plików XML czy klas, które zostały w PHP5 przepisane od nowa, przez co są dużo prostsze i łatwiejsze w użyciu. Niemniej większość skryptów pisanych w PHP4 może pokazywać błędy w PHP5, dlatego starsza edycja była prawie przez dwa lata podtrzymywana i rozwijana.
Spis treści
1. Absolutne podstawy
1.1. PHP w HTML-u
1.2. Pierwszy skrypt
1.3. Błędy ludzka rzecz
1.4. Kończenie instrukcji
1.5. Komentarze
2. Zmienne
2.1. Podstawy
2.2. Działania na zmiennych
2.3. Typy zmiennych
2.4. Zmienne predefiniowane przez serwer
2.5. Stałe
3. Operatory
3.1. Operatory
3.2. Operatory arytmetyczne
3.3. Przypisanie
3.4. Operatory porównania
3.5. Kontrola błędów
3.6. Inkrementacja i dekrementacja
3.7. Trochę logiki - operatory logiczne
3.8. Operatory łańcuchowe (stringów)
4. Struktury kontrolne
4.1. Instrukcje warunkowe
4.2. Pętla for
4.3. Pętla while
4.4. Pętla do..while
4.5. Pętla foreach
4.6. Switch
4.7. Przerwania wykonania pętli
4.8. Dwie alternatywy
5. Tablice
5.1. Co to jest tablica?
5.2. Tablice asocjacyjne
5.3. Przeglądanie tablic
5.4. Zamiana tablic na stringi i odwrotnie
6. System plików
6.1. Wstęp
6.2. Wewnętrzny wskaźnik pliku
6.3. Odczyt z pliku
6.4. Zapis do pliku
6.5. Blokowanie plików
6.6. Trochę statystyk
6.7. Kopiowanie
6.8. Zmiana nazwy
6.9. Usuwanie plików
6.10. Katalogi
6.11. Prawa dostępu
7. Załączanie zewnętrznych plików
7.1. Cztery funkcje - jedno działanie
7.2. Najbardziej znane: include() i require()
7.3. Ograniczenia include() i require()
7.4. Młodsi bracia: include_once() i require_once()
8. Przekazywanie zmiennych
8.1. Wstęp
8.2. Metoda GET
8.3. Metoda POST
8.4. Odzyskać zmienną
8.5. Ciasteczka
9. Funkcje
9.1. Wielokrotne użycie kodu - funkcje, argumenty, return
9.2. Wiele argumentów
9.3. Zmienne spoza funkcji
9.4. Zmienne statyczne
9.5. Funkcje zmienne
10. Klasy - wstęp w PHP4
10.1. Różnice pomiędzy PHP4 i PHP5
10.2. Wstęp do klas
10.3. Klasy potomne
10.4. Operator :: (dwa dwukropki)
10.5. Operator parent - odniesienie do rodzica
11. Klasy w PHP5
11.1. Różnice pomiędzy PHP4 i PHP5
11.2. Automatycznie wczytywanie
11.3. Konstruktory i destruktory
11.4. Referencje i klonowanie
11.5. 3xP, czyli klasy publiczne (public), chronione (protected) i prywatne (private)
11.6. Interfejsy
11.7. Abstrakcje
11.8. Metody i zmienne statyczne
11.9. __call()
11.10. __set()
11.11. __get()
11.12. final
11.13. instanceof
12. Data i czas
12.1. Podstawy
12.2. Kilka przydatnych funkcji
12.3. Sprawdzanie daty
12.4. Data -> timestamp
12.5. timestamp -> data
13. Upload plików
13.1. Kilka słów o uploadzie
13.2. Najpierw formularz
13.3. Odbiór pliku w teorii
13.4. Kody błędów
13.5. Upload wielu plików
14. Sesje
14.1. Wstęp do sesji
15. Dynamiczna grafika
15.1. Jak to działa?
15.2. Podstawy
15.3. Pierwsze rysunki - deklaracja kolorów
15.4. Wypełnianie
15.5. Linie
15.6. Kwadraty
15.7. Elipsy
15.8. Kształty bliżej nieokreślone
15.9. Łuki
15.10. Napisy
15.11. Ciąg znaków
15.11. Styl ciągu znaków
15.12. Licznik wyświetlający grafikę
16. Referencje
16.1. Kilka słów o referencjach
16.2. Zalety referencji
16.3. Koniec referencji
17. Obsługa wyjątków
17.1. Nowa obsługa błędów
17.2. Rozbudowa klasy Exception
17.3. Metoda getTrace() klasy Exception
18. Bezpieczeństwo skryptów
18.1. Include i require - ich niebezpieczeństwa
18.2. Konfiguracja php.ini
18.3. Dane od użytkowników
19. Baza danych MySQL
19.1. Wstęp
19.2. Struktura bazy
19.3. Połączenie z bazą
19.4. Język SQL
19.5. Pierwsze operacje, nowa baza
19.6. Nowe tabele
19.7. Wstawianie danych
19.8. Wybieranie konkretnych rekordów
19.9. Modyfikacja rekordów
19.10. Usuwanie rekordów
19.11. Funkcje do obsługi MySQL-a
19.12. mysql_num_rows()
19.13. mysql_fetch_array()
19.14. mysql_insert_id()
19.15. mysql_result()
19.16. mysql_error()
19.17. Wyświetlanie wyniku zapytania
20. Smarty
20.1. Instalacja
20.2. Składnia Smarty
20.3. Komentarze
20.4. Zmienne
20.5. Funkcje
20.6. Inne delimitery tagów Smarty
1. Absolutne podstawy
1.1. PHP w HTML-u
Użycie PHP jest bardzo łatwe i sprowadza się do wstawienia kodu bezpośrednio do pliku ze stroną WWW. Jednakże pliki zawierające skrypty PHP powinny mieć najczęściej rozszerzenie PHP, chyba że konfiguracja serwera wskazuje inaczej. Jeśli serwer napotka taki plik, to wysyła go do parsera PHP, który przetwarza skrypt w nim zawarty i odsyła gotowy kod HTML. Skrypty można wstawiać na cztery sposoby:
<? echo "Skrypt PHP, najprostszy sposób”; ?>
<?php echo "Prawie to samo, ale częściej stosowane”; ?>
<script type="text/php”>echo "Metoda dla tych, co lubią dużo pisać”</script>
<% echo "Metoda znana z ASP, nie każdy serwer ją obsługuje”; %>
1.2. Pierwszy skrypt
Teraz możemy już napisać pierwszy skrypt w PHP. Jego postać jest następująca:
<?php echo "Hello World!"; ?> |
Plik zapisujemy jako pierwszy.php i umieszczamy na naszym koncie WWW (koniecznie z obsługą PHP). Otwierając go w przeglądarce, zobaczymy tylko tekst Hello World!. A teraz mała analiza:
1. elementy <?php oraz ?> to odpowiednio otwarcie i zakończenie bloku kodu PHP,
2. element echo „Hello World!”; to niby-funkcja zwracająca do przeglądarki podany w cudzysłowie tekst.
Procedury echo można użyć na dwa sposoby: echo ("tekst”); oraz echo "tekst”;, przy czym różnią się one tylko sposobem wyświetlania tekstu pochodzących z wielu źródeł. W wypadku echo („tekst”); treści możemy wstawić, oddzielając je przecinkiem, np. echo („tekst1”, „tekst2”, „tekst3”);, a w echo „tekst”;, łącząc je kropkami, np. echo „tekst1”.”tekst2”.”tekst3”;. Oba te sposoby dają taki sam wynik, czyli:tekst1tekst2tekst3.
Jeżeli chcemy oddzielić teksty spacjami, należy je dodać do funkcji echo, na przykład tak:
echo "tekst1 "."tekst2 "."tekst3" |
1.3. Błędy ludzka rzecz
Pomyłki zdarzają się każdemu. Jeśli zrobimy jakąś literówkę lub poważniejszy błąd składniowy, parser poinformuje nas o tym następującym komunikatem: parse error: parse error, unexpected T_ECHO, expecting ',' or ';' in /var/www/kurs_php/kurs.php on line 3.
W informacji tej zawierają się informacje o rodzaju błędu oraz pliku i linii kodu, w którym się on znalazł.
Prostą i skuteczną metodą „debugowania” jest wstawianie w kluczowych miejscach skryptu procedury echo wyświetlającej wartości ważnych zmiennych. W ten sposób można się łatwo zorientować, czy skrypt w określonym miejscu zawiera dane, których oczekiwaliśmy. Przed pisaniem skryptów dla danego serwera warto się też zapoznać z funkcją phpinfo();. Pokazuje ona pełną konfigurację parsera PHP na serwerze, listę zmiennych środowiskowych, listę zainstalowanych modułów oraz wiele innych potrzebnych danych. Wystarczy wpisać w pustym pliku <? phpinfo(); ?> i wysłać ten plik na serwer.
1.4. Kończenie instrukcji
Każdą instrukcję w PHP (tak jak w wielu innych językach) należy zakończyć znakiem ; (średnik). Każde zakończenie instrukcji bez średnika spowoduje, że skrypt nawet nie zacznie być interpretowany przez parser. Od tej reguły jest tylko jeden wyjątek - średnikiem nie trzeba kończyć ostatniej instrukcji w bloku kodu PHP:
<? |
1.5. Komentarze
Komentarze to specjalnie oznaczone fragmenty kodu, które są omijane przez parser. Służą do różnych celów - można w nich umieszczać np. uwagi do danego fragmentu skryptu, znaki copyright czy uwagi do innych członków grupy roboczej. Istnieją trzy sposoby oznaczania komentarzy:
// komentarz jednoliniowy, tylko do końca linii,
# komentarz jednoliniowy, sposób znany z shella,
/* komentarz wieloliniowy - można oznaczyć nim np. całe fragmenty kodu, aby tymczasowo wyłączyć je z wykonywania */ .
2. Zmienne
2.1. Podstawy
Na razie tylko wyświetlaliśmy tekst za pomocą procedury echo. Teraz PHP pokaże, na co go naprawdę stać, czyli przyszedł czas na obliczenia. Porcje danych są przechowywane w zmiennych. Są to lokowane na czas wykonywania skryptu fragmenty pamięci, w których można przechowywać praktycznie dowolne dane.
Zmienną w PHP oznaczamy znakiem $ (dolar). Rozróżniana jest wielkość znaków, a więc $zmienna, $ZmIeNNa i $ZMIENNA nie przechowują tych samych danych. Jest jeszcze jedna zasada nazywania zmiennych - nazwa musi się zaczynać od litery (wielkiej lub małej) lub znaku _ (podkreślenie). Dalej mogą wystąpić także cyfry. Oto kilka przykładowych nazw zmiennych:
$liczba_wszystkich_wpisow,
$_czy_prawda,
$czyPrawda,
$numerek.
Zgodnie z przyjętą konwencją, jeśli w nazwie zmiennej ma wystąpić kilka wyrazów, nie powinno się ich oddzielać znakiem podkreślenia ('_'), ale napisać każdy z nich (oprócz pierwszego) wielką literą (np. $liczbaWszystkichWpisów). W PHP nie musimy się martwić strukturami używanymi w innych językach programowania, takimi jak np. deklarowanie zmiennej czy jej typu. Wystarczy napisać po prostu:
<? |
I już tworzona jest nowa zmienna (o ile taka już nie istnieje) i zapisywana jest jej wartość.
2.2. Działania na zmiennych
Zmienna jest strukturą, która (o ile przechowuje liczby) może być traktowana właśnie jak liczba. PHP pozwala na wykonywanie na nich standardowych działań dodawania, odejmowania, mnożenia i dzielenia. Dla przykładu:
<? |
W tym przykładzie wartość zmiennej $c wyniesie 20 (suma), $d = 10 (różnica), $e = 75 (mnożenie) i $f = 3 (dzielenie). Wytłumaczenia wymaga znak '%' (modulo) - jest to operator reszty z dzielenia. W tym wypadku $g wyniesie 0, bo reszta z dzielenia 15 przez 3 wynosi właśnie zero.
2.3. Typy zmiennych
W PHP istnieje pięć podstawowych typów zmiennych:
liczby całkowite (integer),
liczby rzeczywiste (double),
ciągi (string),
tablice (array),
obiekty (object).
PHP, kiedy zachodzi taka potrzeba, automatycznie zamienia rodzaje zmiennych. Zdarza się jednak, że nie jesteśmy zadowoleni z wyniku takiej zamiany. Pozostaje wtedy jedno wyjście - rzutowanie. W PHP mamy do czynienia z dwoma typami tej procedury: cast oraz settype(). Pierwszy służy do jednorazowej zamiany typu zmiennej. Wystarczy dopisać przed nazwą zmiennej typ w nawiasie, aby uzyskać pożądany wynik. Dla przykładu:
<? |
W tym wypadku dozwolone typy rzutowań to:
(int), (integer) - rzutuj do typu całkowitego,
(real), (double), (float) - rzutuj do typu rzeczywistego,
(string) - rzutuj do ciągu,
(array) - rzutuj do tablicy,
(object) - rzutuj do obiektu.
Rzutowanie cast stosuje się także w zabezpieczaniu skryptu przed możliwymi atakami. Więcej o tym w rozdziale „Bezpieczeństwo skryptów”.
Druga możliwość to użycie funkcji settype(), która pobiera dwa argumenty. Pierwszy to nazwa zmiennej, której typ chcemy ustalić, a drugi to docelowy typ zmiennej. (dozwolone to „integer”, „double”, „string”, „array” i „object”). Dla przykładu:
<? |
Po wykonaniu tego przykładu pokaże się liczba 10, ponieważ liczba 10,3 została zamieniona na liczbę całkowitą.
2.4. Zmienne predefiniowane przez serwer
W każdym skrypcie możemy użyć kilku zdefiniowanych i gotowych do użycia zmiennych. Ich wartości zależą od ustawień serwera. Oto najważniejsze z nich:
DOCUMENT_ROOT - zwraca katalog główny serwera WWW, gdzie umieszczony jest skrypt,
HTTP_ACCEPT_CHARSET - zwraca zawartość nagłówka „Accept-Charset” z aktualnego zapytania, jeśli taki istnieje, np. iso-8859-1, utf-8 etc.,
HTTP_HOST - zwraca zawartość nagłówka „Host” z aktualnego zapytania, jeśli taki istnieje,
HTTP_REFERER - zwraca adres strony (jeśli taka istniała), która przekierowała do przeglądarkę do naszej witryny. Wartość ta powinna być ustalona przez przeglądarkę, ale nie wszystkie aplikacje sobie z tym radzą. Zmienna ta jest używana często przy tworzeniu statystyk WWW,
HTTP_USER_AGENT - zwraca zawartość nagłówka „User-Agent” z zapytania, jeśli taki istnieje. Jest to ciąg informujący o przeglądarce, która została użyta do wyświetlenia bieżącej strony,
REMOTE_ADDR - zwraca adres IP użytkownika, który wyświetlił bieżącą stronę,
SCRIPT_FILENAME - zwraca ścieżkę do wykonywanego skryptu,
SERVER_ADMIN - zwraca adres administratora serwera WWW. Jeśli skrypt działa na wirtualnym serwerze, to będzie to wartość podana dla tego wirtualnego serwera,
SERVER_PORT - zwraca port na serwerze, którego użyto do połączenia. Dla standardowych połączeń będzie to wartość 80,
SERVER_SIGNATURE - zwraca ciąg zawierający wersję i nazwę wirtualnego hosta, który jest dodawany do stron generowanych przez serwer,
SCRIPT_NAME - zwraca ścieżkę do wykonywanego pliku. Jest to przydatne w wypadku skryptów odwołujących się do samych siebie.
Powyższe zmienne wyświetlamy w następujący sposób:
<? |
2.5. Stałe
W PHP istnieją też obiekty, które nazywamy „stałymi” - są to rodzaje zmiennych, które przechowują pewne określone dane i nie można zmienić ich wartości w trakcie wykonywania skryptu. W zapisie różnią się one od tradycyjnych zmiennych tym, że nie mają znaku dolara na początku. PHP tworzy automatycznie kilka stałych gotowych do wykorzystania w skryptach:
__FILE__ - zawiera nazwę pliku, który jest akurat przetwarzany. Jeśli stała ta znajduje się w pliku, którego treść znajduje się w innym zbiorze (include), to również zwracana jest nazwa pliku podstawowego, gdzie użyto stałej,
__LINE__- zawiera numer akurat przetwarzanej linii skryptu. Jeśli stała ta znajduje się w pliku, którego treść znajduje się w innym zbiorze (include), to również zwracany jest numer linii z pliku podstawowego,
PHP_VERSION - zawiera wersję akurat używanego parsera PHP,
PHP_OS - zawiera nazwę systemu operacyjnego, na którym uruchamiany jest parser PHP.
Własne stałe można definiować funkcją define(), która pobiera dwa argumenty - nazwę stałej i jej wartość. Dla przykładu:
<? |
3. Operatory
3.1. Operatory
Operatory to specjalne znaki, pozwalające na wykonywanie operacji na zmiennych. Pomagają one też wyłapywać błędy w kodzie, jak również porównywać zmienne.
3.2. Operatory arytmetyczne
Poznaliśmy je już w poprzednim rozdziale. Są to: +, -, *, / i %, czyli odpowiednio: dodawanie, odejmowanie, mnożenie, dzielenie i dzielenie modulo (zwraca resztę z dzielenia).
3.3. Przypisanie
Operator przypisania wygląda jak znak 'równa się' (=). Jest to przypisanie wartości wyrażenia z jego prawej strony (wyrażenie, czyli zmienna lub funkcja zwracająca jakąś wartość) do zmiennej z jego lewej strony. Dla przykładu:
<? |
3.4. Operatory porównania
Służą do porównywania wartości stojących po ich lewej i prawej stronie. Poniższa tabela zawiera kompletną listę operatorów porównania w PHP.
Przykład |
Nazwa |
Opis |
$a == $b |
Równy |
Zwraca TRUE, jeśli $a jest równe $b. |
$a === $b |
Identyczny |
Zwraca TRUE, jeśli $a jest równe $b i obie zmienne są tego samego typu (tylko w PHP 4). |
$a != $b |
Różny |
Zwraca TRUE, jeśli $a nie jest równy $b. |
$a <> $b |
Różny |
Zwraca TRUE, jeśli $a nie jest równy $b. |
$a !== $b |
Nie identyczny |
Zwraca TRUE, jeśli $a nie jest równy $b lub nie są tego samego typu (tylko w PHP 4). |
$a < $b |
Mniejszy niż |
Zwraca TRUE, jeśli $a jest mniejszy od $b. |
$a > $b |
Większy niż |
Zwraca TRUE, jeśli $a jest większy od $b. |
$a <= $b |
Mniejszy lub równy |
Zwraca TRUE, jeśli $a jest mniejszy lub równy $b. |
$a >= $b |
Większy lub równy |
Zwraca TRUE, jeśli $a jest większy lub równy $b. |
3.5. Kontrola błędów
W PHP4 istnieje operator wyciszający błędy - jest to @ (małpa). Umieszczony przed dowolnym wyrażeniem zapobiega wyświetleniu komunikatu o błędzie. Jeśli jest to błąd typu fatal error, to skrypt zostanie zatrzymany, ale treść błędu i tak nie zostanie wyświetlona. W komercyjnych aplikacjach bardzo często stosuje się operator @, gdyż wręcz niedopuszczalne jest pojawienie się błędu (na przykład typu parse error) w programie.
3.6. Inkrementacja i dekrementacja
Jeśli zachodzi potrzeba podniesienia lub zmniejeszenia wartości danej zmiennej o 1, nie musimy od razu pisać $a=$a+1; etc. Poniższa tabela pokazuje, w jaki sposób wykorzystać do tego celu wbudowane w PHP mechanizmy.
Przykład |
Nazwa |
Opis |
++$a |
Preinkrementacja |
Najpierw zwiększa wartość $a o jeden, a potem zwraca $a. |
$a++ |
Postinkrementacja |
Najpierw zwraca $a, a potem zwiększa $a o jeden. |
--$a |
Predekrementacja |
Najpierw zmniejsza wartość $a o jeden, a potem zwraca $a. |
$a-- |
Postdekrementacja |
Najpierw zwraca $a, a potem zmniejsza $a o jeden. |
3.7. Trochę logiki - operatory logiczne
Operatory te wykorzystuje się głównie w instrukcjach warunkowych typu if, jeśli umieszczony został więcej niż jeden warunek.
Przykład |
Nazwa |
Opis |
$a and $b |
I |
Zwraca TRUE, jeśli zarówno $a, jak i $b są TRUE. |
$a or $b |
Lub |
Zwraca TRUE, jeśli $a lub $b są TRUE. |
$a xor $b |
Wyłącznie-Lub |
Zwraca TRUE, jeśli $a lub $b jest TRUE, ale nie jednocześnie. |
! $a |
Nie |
Zwraca TRUE, jeśli $a nie jest TRUE. |
$a && $b |
I |
Zwraca TRUE, jeśli zarówno $a, jak i $b są TRUE. |
$a || $b |
Lub |
Zwraca TRUE, jeśli $a lub $b jest TRUE. |
3.8. Operatory łańcuchowe (stringów)
Istnieją dwa takie operatory . (kropka) oraz .= (kropka+znak równości). Pierwszy z nich łączy dwa ciągi z jego lewej i prawej strony, a następnie zapisuje wynik do zmiennej. Dla przykładu:
<? |
Drugi operator łańcuchowy (.=) dopisuje wartość ciągu z jego prawej strony do zmiennej z jego lewej strony. Dla przykładu:
<? |
4. Struktury kontrolne
Czas zająć się tworzeniem bardziej rozbudowanych programów - takich, które odpowiednio reagują np. na dane wprowadzone przez użytkownika. Służą do tego pewne fragmenty kodu zwane strukturami kontrolnymi.
4.1. Instrukcje warunkowe
Instrukcje warunkowe są znane ze wszystkich języków programowania. Używa się ich do sprawdzenia tego, czy dany warunek jest prawdziwy, i na podstawie wyniku takiego zapytania wykonania określonego fragmentu kodu. Jeśli dane sprawdzenie nie przynosi oczekiwanego rezultatu, sprawdzany jest kolejny warunek (i ewentualnie uruchamia przypisany mu blok kodu). W wypadku gdy nie jest spełniony żaden warunek, wykonuje się jeszcze inny blok instrukcji. Dla przykładu:
<? |
Oczywiście nie wszystkie bloki struktury kontrolnej IF muszą być zawsze wykorzystywane. Konieczny jest jedynie blok if..,, a bloki else if i else można umieścić lub nie (w zależności od aktualnej potrzeby).
Za warunek można uznać wszystko, co zwraca jakąś wartość, czyli zmienną, instrukcję warunkową lub funkcję. Za prawdę uznawane jest wszystko, co ma wartość większą od 0. Dla przykładu:
<? |
Instrukcje mogą być też lokowane jedna w drugiej. Dla przykładu:
<? |
Jednak powyższy przykład można zastąpić innym - mniej skomplikowanym - łącząc wyrażenia operatorami logicznymi. Dla przykładu:
<? |
Wyrażenia logiczne da się łączyć w jeszcze bardziej skomplikowane struktury, dodając nawiasy i znak ! (wykrzyknik) przed nimi, czyli zaprzeczając wyrażeniu w nawiasie lub pojedynczemu wyrażeniu. Oto dłuższy przykład do przeanalizowania:
<? |
4.2. Pętla for
Pętla FOR jest używana tylko wtedy, gdy zachodzi potrzeba wykonania jakiegoś kodu określoną liczbę razy (założoną z góry przez autora lub pochodzącą ze zmiennej). Składnia tej pętli przedstawia się następująco:
<? |
Przeanalizujmy następujący przykład, aby się przekonać, jak prosta w użyciu jest pętla FOR:
<? |
W powyższym kodzie $i=10 oznacza początkową wartość licznika pętli. Najpopularniejszym sposobem jest oznaczenie jej jako i, ale można ją nazwać dowolnie. Wyrażenie $i<20 oznacza, że pętla jest wykonywana, dopóki ten warunek jest prawdą. Wyrażenie $i++ podnosi wartość licznika o 1. Równie dobrze można by wpisać tu $i+=2.
4.3. Pętla while
Kolejnym rodzajem pętli jest pętla WHILE. W tym wypadku nie jest z góry narzucone to, ile razy dany blok instrukcji zostanie wykonany. Jest on wykonywany, dopóki podany warunek jest prawdziwy. Schemat działania tej instrukcji wygląda następująco:
<? |
4.4. Pętla do..while
To specyficzna odmiana pętli WHILE, bo jeśli we WHILE warunek jest na starcie fałszywy, to pętla ani razu nie wykona bloku instrukcji. W wypadku użycia DO…WHILE pętla wykona blok instrukcji przynajmniej raz (nawet wtedy, gdy warunek jest od początku fałszywy). Schemat działania tej instrukcji wygląda następująco:
<? |
4.5. Pętla foreach
Pętla ta jest zaczerpnięta z innego języka programowania - Perla. Ułatwia ona obsługę tablic i tablic asocjacyjnych. Poniższy przykład pokazuje, jak łatwo zamienić pętlę FOR na FOREACH w wypadku korzystania z tablic.
Blok instrukcji:
<? |
jest równoważny zapisowi:
<? |
Atuty FOREACH stają się jeszcze bardziej oczywiste w wypadku obsługi tablic asocjacyjnych.
Blok instrukcji:
<? |
jest równoważny zapisowi:
<? |
4.6. Switch
Switch jest rodzajem skondensowanej instrukcji warunkowej, którą zazwyczaj zastępujemy rozbudowane i wielokrotne użycia ELSE IF. Dla przykładu:
<? |
W pierwszym nawiasie podaje się nazwę zmiennej, której wartość chcemy sprawdzać. Następnie sprawdzamy, czy wartość tej zmiennej to „warszawa”. Jeśli tak jest, skrypt ma wyświetlić zdanie: „Pochodzisz ze stolicy?”. Jeżeli nie, skrypt sprawdza kolejny warunek itd. Bardzo ważne jest słowo BREAK na końcu każdej instrukcji. Jeśli o nim zapomnimy, parser wykona cały kod, aż do kolejnego BREAK lub końca SWITCH. Czasami ominięcie BREAK jest założone przez programistę. Na koniec wyjaśnijmy jeszcze DEFAULT - tutaj należy określić, który blok instrukcji ma zostać wykonany, gdy wartość zmiennej nie zgodzi się z żadnym CASE.
4.7. Przerwania wykonania pętli
Może się zdarzyć, że będziemy chcieli przerwać wykonywania pętli. Służą do tego instrukcje BREAK oraz CONTINUE. Pierwsza z nich powoduje przerwanie wykonywania pętli, a co za tym idzie - dalszej części zawartego w niej kodu. Funkcja CONTINUE powoduje natomiast przerwanie aktualnej iteracji (przebiegu) pętli i wykonanie jej od nowa.
4.8. Dwie alternatywy
Istnieją też składnie alternatywne do tych przedstawionych powyżej. Pierwsza z nich to skrócona wersja instrukcji warunkowej IF. Jej schemat jest następujący:
<? |
W ten sposób możemy np. umieszczać instrukcje warunkowe wewnątrz tekstu wyświetlanego za pomocą funkcji ECHO. Dla przykładu:
echo "Liczba 5 jest ".((5>$a)" |
Koleją możliwością jest niewykorzystywanie nawiasów klamrowych w instrukcjach IF, FOR, SWITCH, WHILE oraz FOREACH. Zamiast klamry otwierającej należy umieścić dwukropek, a na końcu słowo ENDIF, ENDSWITCH bądź inny END... - odpowiedni do użytej pętli. Taka składnia obejmuje też użycie ELSEIF i ELSE:
<? |
5. Tablice
5.1. Co to jest tablica?
Tablice to typy zmiennych, które służą do przechowywania innych zmiennych. Używanie tablic pomaga np. w przeglądaniu wpisów pobranych z bazy danych lub odczytanej listy plików z foldera na serwerze, gdyż można się do nich odwoływać po ich indeksach (liczby całkowite) lub identyfikatorach tekstowych (w tablicach asocjacyjnych). W wypadku identyfikatorów tekstowych należy pamiętać, że zaczynają się one od zera, gdyż często młodzi programiści popełniają tu błąd. Oto przykład przypisania trzech kolejnych wartości do tablicy $tablica.
<? |
Kiedy chcemy po prostu dodać nową pozycję do tablicy, wystarczy zastosować powyższy zapis, pomijając numer klucza w nawiasie kwadratowym. Dla przykładu:
<? |
Elementem tablicy może być dowolna zmienna, nawet inna tablica. Gdy powstanie taka konstrukcja, tablicę nazywamy wielowymiarową i do elementu odwołujemy się poprzez zapis uwzględniający liczbę wymiarów. Dla przykładu:
<? |
5.2. Tablice asocjacyjne
Tablice asocjacyjne to odmiany tablic, w których zamiast indeksów liczbowych występują indeksy tekstowe. Najczęstsze zastosowanie tej struktury danych prezentuje poniższy przykład. Tablica reprezentuje konkretną osobę, a wiersze to jej dane osobowe.
<? |
5.3. Przeglądanie tablic
Czasem będziemy potrzebowali wykonać jakąś operację na wszystkich elementach tablicy. np. porównać ze wzorcem. W wypadku zwykłej tablicy (gdy znamy liczbę jej elementów) wystarczy użyć pętli FOR i następującej konstrukcji:
<? |
Lecz jeśli nie znamy liczby elementów tablicy, bo jest ona zmienna i zależy np. od wprowadzonych wcześniej informacji, należy posłużyć się funkcją sizeof(). Podając jako argument nazwę tablicy, otrzymamy liczbę jej elementów. Dla przykładu:
<? |
Nieco bardziej skomplikowane jest przeglądanie tablicy asocjacyjnej, ale i tutaj użyteczne są dwie konstrukcje. Dla przykładu:
<? |
|
<? |
W pierwszym przykładzie kod zwraca dla każdej iteracji pętli parę zmiennych: $klucz i $wartosc. Zawierają one odpowiednio nazwę klucza i jego wartość. W drugiej konstrukcji należy wyjaśnić funkcje list() i each().
list() - podobnie jak array(), list() nie jest tak naprawdę funkcją, ale elementem składni języka. Używamy list(), aby przypisać listę zmiennych do funkcji zwracającej tablicę wyników (np. explode()),
each() - zwraca bieżącą parę klucza i wartości z tablicy oraz przesuwa kursor tablicy (wewnętrzny wskaźnik tablicy). Aby odczytać tablicę ponownie, używając each(), należy użyć funkcji reset(), co spowoduje powrót na początek tablicy.
Zatem each() zwraca tablicę, w której na pierwszej pozycji jest klucz, a na drugiej wartość, list() natomiast przechwytuje ją i zapisuje do dwóch zmiennych.
5.4. Zamiana tablic na stringi i odwrotnie
Zdarza się, że ciąg znaków trzeba zamienić na tablicę (chociażby przy odczytywaniu danych z pliku). Potrzebna jest wówczas funkcja explode(). Jak sama nazwa wskazuje, funkcja ta rozdziela określony ciąg znaków i tworzy z powstałych elementów tablicę. Funkcja pobiera dwa argumenty: ciąg znaków lub znak, który stanowi element rozdzielający, a także zmienną zawierającą ciąg, który chcemy rozdzielić. Dla przykładu:
<? |
Wywołanie takie zwróci tablicę o nazwie $wpisy z pojedynczymi elementami, które były w oryginalnym ciągu rozdzielone symbolem |.
Elementy tablicy można również tablicę połączyć określonym znakiem (aby je np. zapisać w pliku). Służy do tego funkcja implode(). Pobiera ona dwa argumenty. Pierwszy to ciąg, którymi mają być połączone elementy tablicy, a drugi to nazwa zmiennej tablicy z danymi.
<? |
5.4.1. Sortowanie tablic
Do sortowania tablic - zarówno zwykłych, jak i asocjacyjnych - napisano wiele funkcji. Poniżej opisujemy sposób działania najważniejszych.
asort() - sortuje rosnąco tablice asocjacyjne według wartości kluczy, zachowując przypisanie kluczy do wartości,
arsort() - sortuje malejąco tablice asocjacyjne według wartości kluczy, zachowując przypisanie kluczy do wartości,
ksort() - sortuje rosnąco tablice asocjacyjne według kluczy, zachowując przypisanie kluczy do wartości,
krsort() - sortuje malejąco tablice asocjacyjne według kluczy, zachowując przypisanie kluczy do wartości,
sort() - sortuje rosnąco zwykłe tablice,
rsort() - sortuje malejąco zwykłe tablice,
uasort() - funkcja sortująca tablice asocjacyjne za pomocą zdefiniowanej przez użytkownika funkcji porównującej elementy (nazwa funkcji jest podawana za pomocą drugiego parametru),
usort() - funkcja sortująca zwykłe tablice za pomocą funkcji zdefiniowanej przez użytkownika,
uksort() - funkcja sortująca tablice asocjacyjne według klucza za pomocą funkcji zdefiniowanej przez użytkownika.
5.4.2. Inne przydatne funkcje
array_change_key_case (array wejście [, int wielkość]) - zmienia klucze w tablicy wejście, tak aby były one pisane tylko dużymi lub tylko małymi literami. Zmiana zależy od ostatniego opcjonalnego parametru case. Można do niego przekazać jedną z dwóch stałych: CASE_UPPER lub CASE_LOWER. Domyślną wartością jest CASE_LOWER. Indeksy liczbowe będą pozostawione,
array_flip (trans) - zwraca tablicę w odwróconym porządku, tzn. klucze z tabeli trans stają się wartościami, a wartości trans stają się kluczami. Zauważmy, że wszystkie wartości tablicy trans muszą mieć poprawne klucze, tzn. muszą być albo typu integer, albo string. Jeśli wartość nie ma prawidłowego typu, wyświetlone zostanie ostrzeżenie, a para klucz i wartość nie będzie odwrócona,
array_fill (indeks_początkowy, num, wartość) - wypełnia tablicę wartością wartość, począwszy od indeksu indeks_początkowy przez num kolejnych elementów tablicy,
array_pop (tablica) - zdejmuje i zwraca ostatnią wartość tablicy tablica, skracając tę tablicę o jeden element. Jeśli tablica jest pusta (lub nie jest tablicą), zwracana jest wartość NULL,
array_push (tablica, wartosc [, wartosc ...]) - traktuje zmienną tablica jako stos i wstawia przekazane parametry na koniec podanej tablicy. Długość parametru tablica zwiększa się o liczbę przekazanych wartości. Funkcja zwraca nową liczbę elementów tablicy,
array_shift (tablica) - usuwa pierwszą wartość parametru tablica i zwraca go, skracając tę tablicę o jeden element i przesuwając wszystkie pozostałe elementy w dół. Jeśli tablica jest pusta (lub nie jest tablicą), zwracana jest wartość NULL,
array_unshift ( tablica, wartość, [wartosc...]) - wstawia jeden lub więcej przekazanych jako parametry elementów na początek tablicy tablica. Zauważmy, że lista elementów jest wstawiana jako całość, więc elementy zostają w takim samym porządku. Funkcja zwraca nową liczbę elementów w tablicy tablica,
array_search (igła, stóg_siana [, ścisły]) - przeszukuje stóg_siana w poszukiwaniu parametru igła i zwraca odpowiedni klucz, jeśli został on znaleziony, lub FALSE w przeciwnym wypadku. Jeżeli trzeci parametr ścisły jest ustawiony na TRUE, to array_search() porówna także typy parametru igła z tymi z parametru stóg_siana.
6. System plików
6.1. Wstęp
W tej części zajmiemy się metodami pozwalającymi na przechowywanie danych w plikach, czyli tzw. płaskimi bazami danych. Opiszemy tutaj, jak otwierać plik oraz czytać i zapisywać do nich informacje.
Wszystkie funkcje obsługujące pliki jako pierwszy parametr pobierają zmienną - tzw. uchwyt do pliku. Jest to specjalna nazwa zwracana przez funkcję otwierającą plik - fopen() - która jednoznacznie identyfikuje dany zbiór. Aby otworzyć plik, należy użyć funkcji fopen(). Pobiera ona dwa parametry. Pierwszy to nazwa pliku do otwarcia, a drugi to tryb otwarcia. Ten ostatni określa cel, w jakim otworzyliśmy zbiór. Istnieje pięć takich trybów:
r - plik tylko do odczytu (wewnętrzny wskaźnik pliku umieszczany jest na początku zbioru),
r+ - plik do odczytu i zapisu (wewnętrzny wskaźnik pliku umieszczany jest na początku zbioru),
w - plik tylko do zapisu (wewnętrzny wskaźnik pliku umieszczany jest na końcu zbioru). Należy tutaj dodać, że zawartość pliku jest niszczona (długość pliku jest zmieniana na zero), a jeśli plik nie istnieje, PHP próbuje go stworzyć,
w+ - plik do odczytu i do zapisu (wewnętrzny wskaźnik pliku umieszczany jest na końcu pliku). Zawartość pliku jest niszczona (długość pliku jest zmieniana na zero). Jeśli plik nie istnieje, PHP próbuje go stworzyć,
a - plik tylko do zapisu (wewnętrzny wskaźnik pliku umieszczany jest na końcu pliku). Jeśli plik nie istnieje PHP, próbuje go stworzyć.
Wewnętrzny wskaźnik pliku określa miejsce, w którym mają być zapisywane dane lub (przy procedurze odczytującej po jednym znaku) który znak ma być odczytany.
Aby otworzyć plik do odczytu, wystarczy wpisać kod:
<? |
Po zakończeniu używania pliku można (ale nie trzeba) go zamknąć. Służy do tego funkcja fclose(wskaznik_do_pliku). Dla przykładu:
<? |
6.2. Wewnętrzny wskaźnik pliku
Wewnętrzny wskaźnik pliku określa, skąd w pliku mają być odczytywane dane lub gdzie mają być zapisywane. Przesuwa się on automatycznie dalej po każdej procedurze odczytania określonej porcji danych z pliku. Czasem jednak chcemy odczytać np. 25. znak z pliku. Nie trzeba wtedy czytać po kolei każdego znaku, aby dojść do tego właściwego.
Wystarczy użyć funkcji fseek(). Pobiera ona trzy argumenty. Pierwszy to oczywiście uchwyt do pliku, kolejny to przesunięcie, a trzeci (opcjonalny) to rodzaj przesunięcia. Dostępne są trzy wartości przesunięcia:
SEEK_SET - ustawia wskaźnik na pozycję określoną poprzez przesunięcie (domyślne),
SEEK_CUR - ustawia wskaźnik na pozycję równą aktualnej i uwzględnia przesunięcie,
SEEK_END - ustawia wskaźnik na koniec pliku i uwzględnia przesunięcie. Jeśli chcemy ustawić wskaźnik w konkretnej odległości (liczby znaków) od końca zbioru, przesunięcie musi być ujemne.
Istnieje też funkcja rewind(), która pobiera jako argument uchwyt do pliku i przesuwa wskaźnik na jego początek.
6.3. Odczyt z pliku
Jest kilka możliwości odczytu danych z pliku. Pierwsza to odczyt po kolei po jednym znaku. Służy do tego funkcja fgetc(). Wystarczy jako argument podać tylko uchwyt do pliku. Zwraca ona jeden odczytany znak lub false, jeśli natrafimy na koniec zbioru.
Ważne jest to, że aby sprawdzić, czy funkcja oddała wartość false, należy użyć operatora === lub !==, ponieważ przy użyciu == lub != wartości „„ (pusty string), lub 0 dzięki zamianie typów zmiennych w PHP też będą interpretowane jako false. Dla przykładu:
<? |
Kolejną możliwością jest odczyt linijka po linijce. Służy do tego funkcja fgets(). Jako parametry należy podać uchwyt do pliku i opcjonalnie maksymalną długość odczytanej linii. Czytanie linii kończy się, gdy funkcja dojdzie do końca linii (znak nowej linii jest dołączany do zwróconej wartości) lub do końca pliku. W PHP do 4.3 wartością domyślną było 1024 znaki, od wersji 4.3.0, gdy nie podany jest parametr określający długość, czytane są całe linijki (do końca).
Można też odczytać od razu cały plik. Wystarczy użyć funkcji fread(). Jej argumentami są: uchwyt do pliku i liczba znaków, jaka ma być odczytana. Często jako liczbę znaków podaje się całkowitą długość pliku, obliczoną funkcją filesize(nazwa_pliku). Dla przykładu:
<? |
Jeśli podana ilość danych do odczytania jest mniejsza niż długość pliku, to po ponownym wywołaniu tej funkcji zwróci ona dane, od momentu gdzie zakończyło się poprzednie czytanie z pliku.
Kolejna możliwość to odczyt całego pliku za pomocą tylko jednej linijki kodu:
<? |
Ale już od PHP w wersji 4.3 istnieje dla powyższej instrukcji dużo lepsza alternatywa - funkcja file_get_contents(). Wystarczy podać jako argument nazwę pliku - tym razem nie jest to uchwyt, czyli pliku nie trzeba otwierać, używając fopen() 0 - a funkcja zwróci całą zawartość pliku. Dla przykładu:
<? |
Kolejną (już ostatnią) metodą odczytywania zawartości pliku jest przeniesienie jego zawartości do tablicy, gdzie każdy wpis odpowiada jednej linii z pliku. Służy do tego funkcja file(), której wystarczy podać tylko nazwę pliku. Zbiór w tym wypadku znów nie musi być otwarty funkcją fopen().
6.4. Zapis do pliku
Z zapisem sprawa jest o tyle ułatwiona, że do dyspozycji jest tylko jedna funkcja - fwrite(), chociaż często w różnych kursach czy nawet skryptach jest używany alias do niej - fputs(). Problem z zapisywaniem jest taki, że nie ma możliwości zapisu na końcu czy w środku pliku.
Można dopisywać tylko na początku. Jeśli więc chcemy coś zapisać na początku już istniejącego zbioru, należy najpierw otworzyć dany plik, odczytać jego zawartość i dopiero wtedy zapisać całość od nowa. Dla przykładu:
<? |
Aby zaś dodać dane na końcu pliku, wystarczy otworzyć go z argumentem a.
6.5. Blokowanie plików
Podczas używania plików w większym serwisie (o dużej liczbie odwiedzin) może się zdarzyć, że w tym samym czasie dwa procesy będą coś próbowały zapisywać do pliku. Jeśli odbędzie się to dokładnie w tym samym czasie, to z zawartością pliku mogą się zdarzyć różne nieprzewidywalne rzeczy. Po to też istnieją blokady pliku. W PHP znajdziemy dwa rodzaje blokad:
blokada dzielona - może być założona przez wiele procesów naraz podczas odczytu,
blokada wyłączna - zakładana podczas zapisu do pliku tylko przez jeden proces.
Aby założyć blokadę, należy użyć funkcji flock(), która pobiera dwa argumenty: uchwyt do pliku i rodzaj blokady. Oto trzy dostępne rodzaje blokady:
LOCK_SH - zakłada blokadę dzieloną (do odczytu),
LOCK_EX - zakłada blokadę wyłączną (do zapisu),
LOCK_UN - zdejmuje blokadę z pliku.
Jeśli zakładanie blokady się powiedzie, to funkcja zwraca wartość true, w przeciwnym wypadku zwracana jest wartość false.
<? |
6.6. Trochę statystyk
W PHP istnieje też kilka funkcji, które zwracają informacje o pliku. Należą do nich:
fileatime(nazwa_pliku) - zwraca datę i czas ostatniego odczytu pliku podane w formacie timestamp,
filemtime(nazwa_pliku) - zwraca datę i czas ostatniej modyfikacji pliku podane w formacie timestamp,
filegroup(nazwa_pliku) - zwraca liczbowy identyfikator grupy, do której należy właściciel pliku,
fileowner(nazwa_pliku) - zwraca identyfikator właściciela pliku,
fileperms(nazwa_pliku) - zwraca prawa dostępu do pliku,
filesize(nazwa_pliku) - zwraca wielkość pliku w bajtach.
Oprócz tego istnieje też kilka funkcji zwracających wartości true lub false. Są to:
is_dir(nazwa_pliku) - informuje o tym, czy zbiór jest katalogiem,
is_executable(nazwa_pliku) - informuje o tym, czy plik jest wykonywalny,
is_file(nazwa_pliku) - informuje o tym, że plik istnieje i jest zwykłym plikiem,
is_readable(nazwa_pliku) - informuje o tym, czy plik można odczytać,
is_writeable(nazwa_pliku) - informuje o tym, czy plik można zapisywać,
is_uploaded_file(nazwa_pliku) - informuje o tym, czy plik został wysłany z formularza.
6.7. Kopiowanie
Do kopiowanie plików służy funkcja copy(). Zwraca ona wartość true, jeśli plik zostanie poprawnie skopiowany, lub false, jeżeli coś pójdzie nie tak. Dla przykładu:
<? |
6.8. Zmiana nazwy
Aby zmienić nazwę zbioru, należy użyć funkcji o nazwie rename(). Może ona też służyć do kopiowania plików i zwraca true lub false, tak samo jak w wypadku copy().
<? |
6.9. Usuwanie plików
Do usuwanie plików służy funkcja o nazwie unlink(). Jako parametr wystarczy podać nazwę pliku. Ważne jest to, by uprawnienia zbioru pozwalały na jego usunięcie, w przeciwnym razie zostanie wyświetlony błąd.
6.10. Katalogi
Aby utworzyć katalog, należy wywyołać funkcję mkdir() i jako parametry podać kolejno: nazwę katalogu do utworzenia i jego prawa dostępu (np. 0777). Funkcja (tak jak prawie wszystkie inne z tej grupy) wartości true lub false w zależności od powodzenia operacji.
Do przeglądania zawartości katalogów służy mechanizm pseudoobiektowy. Przeglądanie zaczynamy funkcją dir(nazwa_folderu), która zwraca obiekt-uchwyt do katalogu. Kolejne pozycje z katalogu pobieramy za pomocą metody read(). Pracę z folderem kończymy metodą close(). Dla przykładu:
<? |
Nieco komplikacji pojawia się w trakcie procesu usuwania katalogów. Służy do tego funkcja rmdir(), której argumentem jest nazwa folderu przeznaczonego do usunięcia. Warunkiem koniecznym do tego, by wszystko się powiodło, jest to, aby usuwany katalog był pusty. Poniżej przykład funkcji rekurencyjnej do usuwania całego katalogu (wraz z plikami i podkatalogami):
<? |
6.11. Prawa dostępu
Unix i jego pochodne to systemy przeznaczone z założenia dla współpracy wielu użytkowników, dlatego wprowadzono coś takiego jak prawa dostępu. Są to zezwolenia dla konkretnych użytkowników lub całych ich grup na wykonanie operacji na danym pliku.
Każdemu plikowi i katalogowi w systemie można przypisać trzy komplety praw. Pierwszy z tych kompletów dotyczy właściciela pliku, drugi grupy użytkowników, a trzeci użytkowników, którzy ani nie są właścicielami zbioru, ani nie należą do grupy. Pojedynczy komplet to suma praw: uruchomienia lub w wypadku katalogu: otwarcia (wartość 1), odczytu (wartość 4) i zapisu (wartość 2). Aby nadać właścicielowi komplet praw, grupie odczyt i zapis, a pozostałym tylko odczyt, należy ustawić prawa „0764” (cyfra zero na początku służy do poinformowania PHP, że liczba zapisana jest w formacie ósemkowym).
Do ustawiania praw dostępu służy funkcja chmod($nazwa_pliku, $tryb), gdzie drugi parametr to prawa dostępu zapisane w formacie ósemkowym. Inne funkcje przydatne przy pracy z systemem zabezpieczeń to chown($nazwa_pliku, $user), zmieniająca właściciela pliku, i chgrp($nazwa_pliku, $grupa), zmieniająca grupę.
Ustawienie odpowiednich praw dostępu to sprawa podstawowa przy tworzeniu skryptów zapisujących coś do pliku lub operujących na katalogach. Bardzo często wyświetla się błąd „Permission denied”, którego poprawienie to właśnie kwestia ustawienia odpowiednich praw dostępu.
7. Załączanie zewnętrznych plików
7.1. Cztery funkcje - jedno działanie
Cały skrypt nie zawsze musi się znajdować w jednym pliku. Jeśli budujemy rozbudowany serwis, na pewno są w nim elementy, które powtarzają się we wszystkich zbiorach. Nie muszą być one umieszczane w każdym pliku ze skryptem - wystarczy stworzyć jeden plik z daną funkcją lub klasą i załączać go do pozostałych. Służą temu cztery funkcje w PHP - na pierwszy rzut oka identyczne, ale różniące się kilkoma szczegółami.
7.2. Najbardziej znane: include() i require()
Najbardziej znanymi funkcjami są include() i require(). Często przez początkujących programistów są używane zamiennie, gdyż na pierwszy rzut oka wydają się działać w sposób identyczny. Ale jest między nimi kilka różnic.
Po pierwsze: generują inne rodzaje błędów. Include() wyświetla przy braku danego pliku błąd warning. Można go wyciszyć operatorem @ i jeśli plik nie jest niezbędny do działania skryptu, nikt nawet nie zauważy, że coś jest nie tak. Inaczej zachowuje się require(), generując błąd fatal error, który zatrzymuje działanie skryptu, nawet jeśli umieścimy przed nim @. Używajmy require() tylko wtedy, gdy plik jest niezbędny do poprawnego działania skryptu.
Po drugie: plik załączany poprzez include() jest wczytywany i załączany, gdy wykonywana jest linia z instrukcją, a wszystkie zmienne dostępne we wczytanym pliku będą dostępne w pliku głównym dopiero od miejsca, gdzie znajduje się instrukcja include(). Jeśli plik zostanie includowany wewnątrz deklaracji funkcji, to wszystkie zmienne w nim zawarte staną się zmiennymi dostępnymi tylko z wewnątrz tej funkcji.
Dla odmiany require() od razu próbuje wczytać żądany plik, nawet jeśli jego wywołanie znajduje się w instrukcji warunkowej (może nie zostać wywołane). Ponadto jeśli funkcja require() znajduje się w pętli, to niezależnie od tego, ile razy byłaby wywoływana, plik zostanie wczytany tylko raz.
7.3. Ograniczenia include() i require()
Obie te instrukcje mają też dwa ograniczenia:
W PHP w wersjach starszych niż 4.3.0 pod kontrolą systemu Windows ani include(), ani require() nie mają możliwości wczytania plików ze zdalnych serwerów,
w pętlach, instrukcjach warunkowych itp. include() i require() muszą być zamykane w nawiasach klamrowych, nawet jeśli są jedynymi instrukcjami. Pamiętajmy, że include() i require() to jedyne instrukcje, która są zamieniane na blok kodu z wczytanego pliku.
Dla przykładu:
<? |
7.4. Młodsi bracia: include_once() i require_once()
Te dwie funkcje dodano w PHP 4.0.1. Działają podobnie jak include() i require(), z tą jedną różnicą, że nawet wielokrotne wywołanie includowania danego pliku poprzez include_once() lub require_once() nie spowoduje wczytania go kilkakrotnie. Rozwiązuje to problem przypadkowego redefiniowania funkcji lub nadpisywania zmiennych przez powtórne wczytanie pliku.
Pamiętajmy, że w systemach nierozróżniających wielkości znaków - np. Windows - poniższy kod spowoduje dwukrotne wczytanie pliku a.php.
<? |
8. Przekazywanie zmiennych
8.1. Wstęp
Po co w ogóle przekazywać zmienne? I gdzie? Wbrew pozorom jest to dość przydatny proces. Bardzo rzadko zdarza się, że plik PHP uruchamiany jest bez żadnych argumentów (czyli właśnie zmiennych z zewnątrz), bo w zasadzie język PHP został stworzony, by przetwarzać wprowadzone dane i zwracać na ich podstawie odpowiedni kod HTML. Istnieją dwa sposoby na przekazanie zmiennej między dwoma plikami PHP - metody GET i POST.
reklama
8.2. Metoda GET
Za pomocą metody GET można przekazać kilka zmiennych, przechowujących małą ilość danych. GET polega na wywołaniu pliku PHP z dodaniem po jego nazwie następującej części:
?zmienna1=wartosc1&zmienna2=wartosc2&zmienna3=wartosc3 |
Oczywiście nazwy zmiennych i ich liczba może być dowolna. Jedynym ograniczeniem jest tutaj to, że większość starszych przeglądarek akceptuje adresy tylko do 1024 znaków. Ale metoda GET to nie tylko same plusy. Należy pamiętać, że wysyłanie zmiennych widocznych w URL prowadzi do sytuacji, w której ktoś może łatwo podmienić ich wartość i np. odczytać plik z hasłami umieszczony na serwerze.
8.3. Metoda POST
Metoda POST służy raczej do przekazywania dużej liczby zmiennych przy zachowaniu podstawowych zasad poufności. Nazwy zmiennych i ich wartości nie są bowiem widoczne, ponieważ są wysyłane jako część nagłówka pliku. Minusem tej metody jest to, że strony z wysłanymi danymi metodą POST nie można np. dodać do Ulubionych.
8.4. Odzyskać zmienną
Zmienne przekazane jako POST lub GET trafiają w najnowszych i tych trochę starszych wersjach PHP (od 4.10) do tablic superglobalnych $_POST, $_GET, $_REQUEST, $_SESSION, $_ENV, $_SERVER oraz $_COOKIE. Wykorzystywane dotychczas tablice o długich nazwach $HTTP_*_VARS są nadal dostępne, aczkolwiek niezalecane w użyciu.
Jednocześnie wycofywana jest obsługa registered_globals, co oznacza, że każda zmienna - niezależnie, czy z metody GET, POST czy z sesji - nie jest już rejestrowana po prostu jako zmienna. Dotychczas było to niebezpieczne i stwarzało możliwości oszukiwania skryptu. Tablice superglobalne, o których wspomnieliśmy ($_GET, $_POST i inne), są asocjacyjne i nazwą danego klucza jest nazwa zmiennej, a wartością - wartość tej zmiennej. Poniżej znajdują się wszystkie tablice superglobalne dostępne w PHP od wersji 4.10.
$GLOBALS - przechowuje wszystkie zmienne globalne w skrypcie,
$_POST - wszystkie zmienne wysłane metodą POST,
$_GET - wszystkie zmienne wysłane metodą GET,
$_SERVER - przechowuje zmienne tworzone przez serwer lub przez środowisko uruchamiania skryptu,
$_ENV - przechowuje zmienne tworzone przez środowisko wykonywania skryptu,
$_COOKIE - przechowuje zmienne pochodzące z ciasteczek,
$_REQUEST - przechowuje zmienne dostarczane przez różne mechanizmy wejścia ($_GET, $_POST, $_ENV, $_COOKIE) razem. Nie jest bezpieczna, ponieważ nie wyszczególnia tego, skąd pochodzi dana zmienna,
$_SESSION - przechowuje zmienne pochodzące z sesji,
$_FILES - przechowuje pliki wgrane na serwer poprzez formularz.
Oto przykład formularza wysyłającego dane o użytkowniku do innego pliku.
plik formularz.html:
<form action="dane.php" method="POST"> |
plik dane.php:
<? |
Plik dane.php pokaże wpisane imię i nazwisko oraz wyświetli płeć w zależności od wartości zmiennej $_POST['plec']. Poszczególne elementy formularza nie wymagają komentarza.
8.5. Ciasteczka
Cookies, czyli tzw. ciasteczka, to małe pliki tekstowe przechowywane na komputerze odbiorcy, w których przetrzymywane są informacje np. o dacie jego ostatniej wizyty lub jego nazwie użytkownika na forum. PHP ma możliwość zapisu ciasteczek dzięki funkcji setcookie(). Argumenty, jakie należy podać, to setcookie(nazwa_zmiennej, wartosc_zmiennej, czas_wygaśnięcia, ścieżka, domena, bezpieczeństwo).
Czas wygaśnięcia to czas, po którym ciastko nie będzie dostępne do odczytu. Podaje się go w formacie timestamp. Przykładowa wartość, jaką można wpisać do czasu_wygasniecia, to np. time()+3600 (ważne godzinę od czasu ustawienia ciastka), time()+3600*24 (ważne dobę) czy time()+3600*24*365 (ważne cały rok).
Jeśli czas nie zostanie podany, to ciastko będzie ważne do zamknięcia przeglądarki. Ścieżka i domena określa kolejno ścieżkę na serwerze i domenę, z których ciastko może zostać odczytane. Jeśli wartość bezpieczenstwo wyniesie 1, to ciastko będzie można odczytać, tylko jeśli połączenie będzie szyfrowane (połączenie SSL).
Domyślnie w ciastkach zapisuje się tylko ciągi znaków. Istnieje jednak możliwość umieszczenia również całej tablicy zapełnionej danymi. Służy do tego funkcja serialize(), która jako parametr pobiera tablicę, a zwraca przekonwertowany ciąg znaków. Odwrotną operację wykonuje funkcja unserialize(), która pobiera ciąg znaków (tablicę zamienioną funkcją serialize()), a zwraca zmienną z tablicą.
9. Funkcje
9.1. Wielokrotne użycie kodu - funkcje, argumenty, return
Często pisząc rozbudowany skrypt, wykorzystuje się pewne fragmenty kodu (np. pobranie porcji danych z bazy i odpowiednie przetworzenie jej) wiele razy. Zamiast wielokrotnie pisać ten sam kod, można stworzyć funkcję, czyli coś w rodzaju podprogramu wykonującego odpowiednie zadania. Często funkcje pisane są w taki sposób, że pobierają argumenty i zwracają odpowiedni wynik. Jedną z prostszych jest funkcja sumująca dwie liczby (podane właśnie jako argumenty) i zwracająca wynik.
<? |
Powyższy kod to deklaracja funkcji o nazwie suma. Gdy chcemy zadeklarować własną funkcję, musimy najpierw napisać słowo kluczowe function, a następnie nazwę funkcji. Nazwa nie może być taka jak już istniejące w PHP funkcje, ponadto musi się zaczynać od litery (później mogą wystąpić cyfry). Rozróżniane są również wielkości liter, tak więc suma() i SuMa() to dwie różne funkcje.
Następnie w nawiasie podajemy parametry funkcji (w tym wypadku są to $liczba1 i $liczba2), a na końcu w nawiasach klamrowych jej treść. Bardzo ważna jest linia zaczynająca się od słowa return. To ona przypisuje wynik działania $suma do wartości, jaką przekazuje sama funkcja.
Dodajmy, że dzięki zapisanemu na końcu drugiego argumentu wyrażeniu =0 wartość drugiej zmiennej nie musi być podana przez użytkownika i przyjmuje zero. Argumenty, których wartość nie musi być podana, koniecznie pobierane są na końcu listy argumentów. Niewłaściwe jest coś takiego jak:
function robKawe($kawa="cappucino", $wielkosc, $typKubka)) |
Aby wyświetlić wynik, należy teraz napisać odpowiedni kod:
<? |
lub taki:
<? |
Return można również użyć do zakończenia działania funkcji w jej trakcie. Dla przykładu:
<? |
W powyższym wypadku funkcja zakończy się, gdy nie zostanie podany chociażby jeden parametr. Gdy tak się stanie, dobrze jest zwracać wartość false, gdyż programista może w ten sposób sprawdzić poprawność obliczeń instrukcją warunkową if. Dla przykładu:
<? |
Ale funkcja nie zawsze musi pobierać i zwracać dane. Można też napisać funkcję (w innych językach - np. w Delphi zwaną procedurą) niepobierającą argumentów i niezwracającą danych. Przykładem może być poniższa funkcja:
<? |
9.2. Wiele argumentów
Możliwe jest też stworzenie funkcji pobierającej nieokreśloną liczbę argumentów. Przykładem może być funkcja unset(), usuwająca zmienne, dla której można podać dowolną liczbę argumentów. Aby osiągnąć coś takiego w samodzielnie napisanej funkcji, należy się posłużyć funkcją func_get_args(), zwracającą w tablicy wszystkie argumenty wysłane do funkcji.
<? |
9.3. Zmienne spoza funkcji
W PHP nie ma bezpośredniego dostępu do zmiennych globalnych poprzez funkcje. Aby użyć w ciele funkcji zmiennej globalnej, należy posłużyć się operatorem global. Dla przykładu:
<? |
Gdyby nie użycie global, nie byłoby dostępu do zmiennej $liczba1 w funkcji, w wyniku czego nie działałaby ona poprawnie.
9.4. Zmienne statyczne
Tym razem zacznijmy od przykładu:
<? |
Jak pewnie wszyscy zauważyli, nie ma on zbytniego sensu, gdyż za każdym wywołaniem funkcji foo() wartość zmiennej jest zerowana i wyświetlane jest zero. Aby ten przykład działał poprawnie, powinien wyglądać tak:
<? |
Wtedy zmienna $a jest zmienną statyczną i za każdym wywołaniem funkcji sprawdzane jest, czy zmienna nie była już wcześniej zadeklarowana. Jeśli tak się stało, to do jej wartości nie jest już przypisywane zero i funkcja zadziała wtedy zgodnie z założeniem (wyświetli po kolei 0, 1, 2).
9.5. Funkcje zmienne
Funkcje zmienne służą do wywołania funkcji o nazwie takiej jak wartość zmiennej. Stanie się tak, gdy po nazwie zmiennej dodamy nawiasy (puste lub z argumentami).
<? |
10. Klasy - wstęp (PHP4)
10.1. Różnice pomiędzy PHP4 i PHP5
Pomiędzy PHP4 i PHP5 istnieją znaczne różnice, jeśli chodzi o tworzenie skryptów bazujących na klasach. Warto jest jednak znać oba modele obiektowe, gdyż wiele skryptów (bazujących na obiektach) nie ma jeszcze swoich wersji na PHP5. Ponadto administratorzy serwerów nie spieszą się z instalowaniem PHP w wersji 5 na swoich serwerach, a z powodu dużej liczby różnic istnieje prawdopodobieństwo, że skrypty obiektowe z PHP4 nie zadziałają pod PHP5 i na odwrót. Jeśli mamy dostęp do serwera z zainstalowanym interpreterem PHP5, nauczmy się od razu modelu klas z PHP5, warto jednak zapoznać się również z ogólnym wstępem do programowania z wykorzystaniem klas.
10.2. Wstęp do klas
Klasy to swego rodzaju szablony, oferujące zbiór zmiennych i funkcji na nich operujących. Dostarczają one pewnej abstrakcji, gdyż tworząc np. klasę zarowka, nie tworzymy konkretnej żarówki, a jedynie ogólne założenie np. odnośnie do jej wyglądu i właściwości. Dopiero gdy gotowa jest deklaracja klasy, ze wszystkimi funkcjami i zmiennymi, można utworzyć nowy obiekt na jej podstawie. Dla przykładu:
<? |
Omówmy powyższy przykład. Otwieramy klasę (class zarowka) i zaczynamy od deklaracji zmiennych wewnątrzklasowych. Muszą one być zadeklarowane przy użyciu słowa kluczowego var i nie wolno im przypisywać na początku żadnej wartości. Następnie mamy do czynienia z funkcją (konstruktorem) - ma ona taką samą nazwę jak sama klasa i uruchamia się zaraz po zadeklarowaniu obiektu. Tutaj właśnie można przypisać wartości do zmiennych.
Zmienne klasy są dostępne poprzez następującą konstrukcję: $nazwaObiektu->nazwa_zmiennej. Jednak podczas pisania klasy nie zawsze wiadomo, jakie będziemy tworzyli obiekty. Należy się wówczas posłużyć pseudozmienną $this, która odwołuje się do aktualnej klasy. Na końcu znajdują się już tylko dwie funkcje do włączania i wyłączania żarówki. Klasa gotowa!
Gdy mamy już klasę zarowka z jej funkcjami i zmiennymi, warto utworzyć obiekt klasy zarowka:
<? |
Utworzone zostały teraz dwa obiekty klasy zarowka: $zarowka o mocy 80 i $malaZarowka o mocy 15. Są to dwa odrębne obiekty, tak więc wywołanie $zarowka->wlacz() spowoduje tylko włączenie się mocniejszej żarówki, gdy $malaZarowka pozostanie wyłączona. Może się tak zdarzyć (przy odpowiednim kodzie - w naszym przykładzie w konstruktorze jest wartość domyślna), że powstaną jakieś błędy podczas użycia klasy. Możliwe jest ich wyciszenie operatorem kontroli błędów - napiszmy po prostu @new.
10.3. Klasy potomne
Gdy trzeba rozszerzyć klasę o nowe funkcje, zmienne lub tylko zmienić działanie już istniejących funkcji, nie musimy definiować od nowa całej klasy. Wystarczy utworzyć klasę potomną i wpisać tylko te funkcje lub zmienne, które się zmieniły lub zostały dodane. Dziedziczenie jest osiągane dzięki słowu extends. Dla przykładu:
<? |
Przy dziedziczeniu wystarczy tylko wypisać te funkcje, których działanie chcemy zmienić - w tym wypadku jest to konstruktor, gdyż dla żarówki energooszczędnej definiowana jest nowa sprawność.
Jeśli w klasie potomnej nie zdefiniujemy konstruktora (funkcji o nazwie takiej jak klasa pochodna), parser będzie próbował uruchomić konstruktor klasy bazowej (mimo że ma on inną nazwę niż klasa pochodna). UWAGA! Klasy muszą być zdefiniowane, zanim będą użyte. Nie można tworzyć klasy zarowkaOsram rozszerzającej klasę zarowka bez uprzedniej deklaracji klasy zarowka.
10.4. Operator :: (dwa dwukropki)
Operator :: pozwala odnosić się do funkcji klasy z pominięciem samego obiektu. Można dzięki niemu uruchamiać funkcje z wewnątrz klasy, bez deklarowania obiektu na niej opartego.
<? |
Pokaże to też na przykładzie klas żarówek. Możesz wyświetlić napis: „Żarówka włączona” z funkcji wlacz() klasy zarowka, nie deklarując żadnego obiektu tej klasy. Po prostu wywołaj kod zarowka::wlacz(), a wyświetli się potwierdzenie włączenia żarówki, nawet jeśli nie istnieje jeszcze nawet obiekt klasy zarowka.
10.5. Operator parent - odniesienie do rodzica
Kiedy piszemy rozbudowane klasy i klasy pochodne, może zajść potrzeba wywołania oryginalnych funkcji z klas nadrzędnych. Służy do tego operator parent. Dla przykładu:
<? |
11. Klasy w PHP5
11.1. Różnice pomiędzy PHP4 i PHP5
W nowym PHP nie wprowadzono wiele zmian. Poprawiono obsługę plików XML, dodano obsługę wyjątków i - co najważniejsze - przebudowano model obiektowy (obsługę klas), który można teraz porównać do tego z C++ czy Javy.
11.2. Automatycznie wczytywanie
Wiele osób piszących skrypty oparte na obiektach umieszcza po jednej definicji klasy w pojedynczym „includowanym” pliku. Jedną z najbardziej irytujących rzeczy jest napisanie listy includes na początku skryptu. Aby to rozwiązać, dodano funkcję __autoload(), która automatycznie wykona zaplanowanie zadania podczas tworzenia obiektu. Wyjątki typu fatal_error zwracane przez __autoload() nie mogą być wyłapane przez blok catch. Dla przykładu:
<? |
11.3. Konstruktory i destruktory
W poprzednich wersjach konstruktor musiał nazywać się tak samo jak klasa. Prowadziło to do pomyłek w tworzeniu klas pochodnych i ich kontruktorach. Teraz konstruktor każdej klasy nazywa się po prostu __construct() - pamiętajmy o dwóch znakach podkreślenia na początku.
Destruktory są natomiast funkcjami uruchamianymi podczas niszczenia obiektu - zazwyczaj jest to właśnie koniec skryptu. Destruktor ma postać __destruct() - również zaczyna się od dwóch znaków podkreślenia. Dla przykładu:
<? |
Skrypt ten da w wyniku następujący tekst:
żarówka włączona
żarowka wyłączona
Tekst z destruktora wyświetli się w tym wypadku, ponieważ nastąpi zniszczenie obiektu (czyli zazwyczaj dzieje się to przy zakończeniu skryptu, chociaż można też to zrobić ręcznie).
11.4. Referencje i klonowanie
W PHP4 tworzenie referencji do obiektu odbywało się za pomocą operatora &. Należało wykonać następujące przypisanie: $obiekt2 =& $obiekt1 (przy czym $obiekt2 = $obiekt1 tworzy po prostu kopię danego obiektu). W PHP5 zmieniono tę kwestię i teraz wyrażenie $obiekt2 = $obiekt1 tworzy referencję. Aby skopiować obiekt, należy użyć funkcji clone(obiekt), która jako parametr pobiera obiekt do skopiowania, a zwraca nowy obiekt ($obiekt2 = clone($obiekt1)). Dla przykładu:
<? |
Powyższy kod wyświetli wyrażenie „zarowka2 jest wylaczona”, ponieważ $zarowka2 jest referencją do $zarowka1, a więc odnosi się do tych samych wartości zmiennych. Jeśli natomiast ktoś chciałby skopiować obiekt, należy zamiast linii $zarowka2 = $zarowka1 wstawić $zarowka2 = clone($zarowka1). Wtedy skrypt zwróci „zarowka2 jest wlaczona”, ponieważ $zarowka2 będzie zupełnie innym obiektem, operującym na innych zmiennych.
11.5. 3xP, czyli klasy publiczne (public), chronione (protected) i prywatne (private)
W PHP5 każda metoda klasy lub jej zmienna może być zadeklarowana za pomocą jednego z trzech słów kluczowych:
public(publiczna) - zmienna lub metoda jest widoczna z całego skryptu,
protected(chroniona) - zmienna lub metoda jest widoczna tylko z obiektu, w którym się znajduje, bądź z jego obiektu podrzędnego,
private(prywatna) - zmienna lub metoda jest widoczna tylko z obiektu, w którym się znajduje.
Dla przykładu:
<? |
W powyższym przykładzie wykorzystaliśmy zmienne, ale rzecz ma się tak samo w wypadku metod w klasie. Metoda publiczna jest widoczna nawet spoza obiektu, chronione i prywatne mogą być natomiast wywołane tylko z wnętrza obiektu. Dla przykładu: $klasa->metoda() wyświetli błąd fatal terror, jeśli metoda() jest chroniona bądź prywatna.
11.6. Interfejsy
Klasy mogą dziedziczyć tylko z jednej klasy nadrzędnej. Prowadziło to czasami do nadmiernego komplikowania drzewa klas. Aby temu zapobiec, w PHP5 wprowadzono interfejsy, które w rzeczywistości nie mają żadnych metod. Interfejs to tylko definicja metody i parametrów, które ona pobiera.
Do klasy można później zaimplementować dowolną liczbę interfejsów, pod warunkiem że w klasie zostaną zadeklarowane metody z interfejsów. Jeśli nie będzie zadeklarowana jakaś metoda wymagana przez zaimplementowany interfejs, wyświetli się fatal error. Aby dołączyć interfejs, należy się posłużyć słowem implements. Dla przykładu:
<? |
11.7. Abstrakcje
W PHP5 wprowadzono abstrakcyjne klasy i metody. Są to specjalne klasy, na podstawie których nie można utworzyć obiektu, ale da się z nich dziedziczyć (to jest właśnie ich podstawowe zadanie). Służą one przede wszystkim jako bazy do tworzenia klas pochodnych. Abstrakcyjne metody to tylko ich deklaracje. Nie mogą zawierać kodu do wykonania, muszą być natomiast rozbudowane w każdej klasie potomnej.
Klasę lub metodę deklaruje się jako abstrakcyjną, wstawiając przed jej nazwę i typ (private, public, protected) słowo kluczowe abstract. W klasie, w której zaimplementowano metodę abstrakcyjną, musi ona być deklarowana z tym samym (bądź niższym) poziomem widoczności. Oznacza to, że jeśli w klasie abstrakcyjnej metoda była chroniona (protected), to w klasie potomnej może ona być chroniona lub publiczna. W przeciwnym wypadku wygenerowany zostanie błąd fatal terror - Access level to klasa2::metoda() must be protected (as in class klasa1) or weaker. Dla przykładu:
<? |
11.8. Metody i zmienne statyczne
Metody i zmienne statyczne to takie, do których dostęp można uzyskać z zewnątrz (bez konieczności definiowania obiektu danej klasy). Elementy statyczne definiowane są za pomocą operatora static, a dostęp do nich musi być ustawiony na publiczny. Nie można też używać wyrażenia $this-> jako odniesienia do aktualnej klasy.
Zamiast tego używajmy self::. Zmienne z metody statycznej nie mogą być pobierane za pomocą operatora ->. Zamiast tego używajmy operatora Paamayim Nekudotayim, czyli :: (podwójnego dwukropka). Dla przykładu:
<? |
11.9. __call()
W wypadku wywołania metody z klasy, która nie istnieje, uruchomiona zostanie metoda __call() (o ile została zadeklarowana). Może ona wykonać dowolny kod, pokazać błąd, zapisać log lub poinformować o tym, że dana metoda nie istnieje. Jeśli metoda __call nie zostanie zadeklarowana, pokaże się fatal error o treści call to an undefinied function. Dla przykładu:
<? |
11.10. __set()
Metoda __set() służy do kontroli procesu zmiany wartości zmiennej w klasie. Ma dwa argumenty: nazwę zmiennej oraz jej nowej wartości. Dla przykładu:
<? |
11.11. __get()
Metoda __get() przechwytuje próby uzyskania dostępu do wartości zmiennej. Dla przykładu:
<? |
11.12. final
Dzięki słowu kluczowemu final nie jest możliwe redefiniowanie metody w klasie pochodnej. Jeśli nastąpi próba redefiniowania metody finalnej, wyświetli się błąd. Dla przykładu:
final function funkcja() {/*instrukcje*/} |
11.13. instanceof
Operator instanceof pozwala na sprawdzenie, czy obiekt jest powiązany z daną klasą lub interfejsem. Jeśli dany obiekt jest utworzony na bazie podanej klasy, jej klasy bazowej lub klasa implementuje dany interfejs, zwracana jest wartość TRUE. Dla przykładu:
<? |
12. Data i czas
12.1. Podstawy
W PHP istnieje bardzo dużo funkcji pozwalających na swobodne operowanie datą i czasem. Podstawowym formatem daty jest timestamp, czyli liczba sekund, która upłynęła od 1 stycznia 1970 roku. Taki zapis daje bardzo dużo możliwości, ponieważ pozwala np. na łatwe porównywanie dwóch dat poprzez ich odjęcie. Łatwo też jest przechowywać taki zapis w bazie danych czy w pliku, a dzięki odpowiednim funkcjom PHP można go bardzo prosto zamienić na format czytelny dla użytkownika.
12.2. Kilka przydatnych funkcji
Najprostszą akcją jest uzyskanie aktualnej daty i czasu w formacie timestamp. Wystarczy użyć funkcji time(). Dla przykładu:
<? |
Czasem zachodzi potrzeba sprawdzenia szybkości jakiegoś rozwiązania, np. fragmentu kodu PHP, i porównania jego wydajności z innym. W takim wypadku oczywiście nie ma sensu używanie funkcji time(), ponieważ zazwyczaj wykonanie całego skryptu PHP trwa niecałą setną sekundy. Z pomocą przychodzi funkcja microtime(). Zwraca ona jednak dane w nieco dziwny sposób - część milisekundowa jest oddzielona spacją od części sekundowej. Poniżej zamieszczamy funkcję interpretującą dane z microtime() i zamieniającą je na coś bardziej czytelnego dla użytkownika:
<? |
Powyższą funkcję można użyć do sprawdzenia czasu wykonywania skryptu. Dla przykładu:
<? |
12.3. Sprawdzanie daty
Aby sprawdzić, czy data wprowadzona np. w formularzu jest poprawna, należy posłużyć się funkcją checkdate(). Pobiera ona kolejno miesiąc, dzień i rok (kolejność zapisu daty w USA) i zwraca wartość TRUE, jeśli data jest poprawna, lub FALSE w wypadku błędu. Funkcja uwzględnia takie kwestie, że np. w roku przestępnym w lutym może być 29 dni.
<? |
12.4. Data -> timestamp
Jeśli dysponujemy już zapisem daty np. wprowadzonej przez użytkownika w formularzu (dzień, miesiąc, rok, godziny, minuty i sekundy osobno), można ją łatwo zamienić na timestamp. Należy wtedy użyć funkcji mktime() i podać w jej parametrach kolejno: godzinę, minuty, sekundy, miesiąc, dzień i rok. Jako ostatni (niewymagany) parametr można podać 1 (jeśli jest to czas letni), 0 (jeżeli jest to czas zimowy) lub -1 bądź nie podawać niczego (wtedy interpreter PHP będzie sam zgadywał, jaki to czas). Dla przykładu:
<? |
Funkcja mktime() nadaje się także do poprawiania błędów w datach i wyliczania ostatnich dni miesiąca. Dla przykładu:
<? |
Wszystkie powyższe przykłady utworzą datę 1 stycznia 1999, a błędy typu 32 grudnia czy 1 dnia 13. miesiąca roku zostaną automatycznie poprawione. Aby wyliczyć ostatni dzień danego miesiąca, należy podać jako argument dzień 0 (zero), a numer miesiąca o jeden większy. Poniższy przykład wyliczy ostatni dzień dla lutego 2000 roku.
<? |
12.5. timestamp -> data
W poprzednim paragrafie pokazywaliśmy, jak utworzyć datę w formacie timestamp. Jednak normalni ludzie mają niestety taką wadę, że nie potrafią czytać daty w tym formacie. Należy im wówczas zaserwować datę w formacie hh:mm:ss dd-mm-rrrr. Aby uzyskać taki efekt z formatu timestamp, należy użyć funkcji date(). Jako pierwszy argument pobiera ona format, w którym zwrócona ma być data, jako drugi zaś (opcjonalnie) datę w formacie timestamp. Funkcja zwraca datę sformatowaną zgodnie z szablonem w argumencie format. W szablonie podaje się specjalne znaki, które są później zamieniane na odpowiednie elementy daty lub czasu. Na przykład G jest zamieniane na godzinę w formacie 24-godzinnym. Oto lista wszystkich znaków do użycia w szablonie w funkcji date:
a - „am” lub „pm”,
A - „AM” lub „PM”,
B - czas internetowy Swatcha,
d - dzień miesiąca, dwie cyfry z zerem na początku, tzn. od „01” do „31”,
D - dzień tygodnia, tekst, trzy litery, np. „Fri”,
F - miesiąc, tekst, pełna nazwa, np. „January”,
g - godzina, format 12-godzinny bez zera na początku, tzn. od „1” do „12”,
G - godzina, format 24-godzinny bez zera na początku, tzn. od „0” do „23”,
h - godzina, format 12-godzinny z zerem na początku, tzn. od „01” do „12”,
H - godzina, format 24-godzinny z zerem na początku, tzn. od „00” do „23”,
i - minuty; tzn. od „00” do „59”,
I (duża litera i) - „1”, jeśli czas oszczędzania światła słonecznego (w Polsce - czas letni); „0”, jeżeli czas standardowy (w Polsce zimowy),
j - dzień miesiąca bez zera na początku, tzn. od „1” do „31”,
l (mała litera L) - dzień tygodnia, tekst, pełna nazwa, np. „Friday”,
L - „1”, jeśli rok przestępny; „0” w przeciwnym wypadku,
m - miesiąc, tzn. od „01” do „12”,
M - miesiąc, tekst, trzy litery, np. „Jan”,
n - miesiąc bez zera na początku, tzn. od „1” do „12”,
O - różnica w stosunku do czasu Greenwich, np. „+0200”,
r - data sformatowana według RFC 822, np. „Thu, 21 Dec 2000 16:01:07 +0200” (dodane w PHP 4.0.4),
s - sekundy, np. od „00” do „59”,
S - standardowy angielski sufiks liczebnika porządkowego, dwie litery, tzn. „st”, „nd”, „rd” lub „th”,
t - liczba dni w danym miesiącu, tzn. od „28” do „31”,
T - strefa czasowa ustawiona na tej maszynie, np. „EST” lub „MDT”,
U - liczba sekund od uniksowej Epoki (1 stycznia 1970 00:00:00 GMT),
w - dzień tygodnia, liczbowy, tzn. od „0” (Niedziela) do „6” (Sobota),
W - numer tygodnia w roku według ISO-8601, tydzień zaczyna się w poniedziałek (dodane w PHP 4.1.0),
Y - rok, cztery liczby, np. „1999”,
y - rok, dwie liczby, np. „99”,
z - dzień roku, tzn. od „0” do „365”,
Z - ofset strefy czasowej w sekundach (tzn. pomiędzy „-43200” a „43200”). Ofset dla stref czasowych na zachód od UTC (południka zero) jest zawsze ujemny, a dla tych na wschód od UTC jest zawsze dodatni.
Jeśli nie chcemy, aby jakiś znak był zamieniony na swój odpowiednik, trzeba przed nim dać znak \. Jeżeli ten znak razem z \ tworzy jakiś znak specjalny, to trzeba go poprzedzić podwójnym \ (np. \t to znak tabulacji, a to znak nowej linii). Dla przykładu:
<? |
Warto dodać, że choć na razie część znaków nie jest używana przez date(), to powinno się cytować wszystkie znaki, które nie mają być zamienione. Dzieje się tak, ponieważ w nowych wersjach PHP do date() wprowadzane będą coraz to nowe symbole. Dla przykładu:
<? |
Poniżej inny przykład użycia date(), zaczerpnięty ze strony php.net:
<? |
13. Upload plików
13.1. Kilka słów o uploadzie
Jeśli dysponujemy kontem WWW np. w Interii lub Lycos, na pewno spotkaliśmy się z klientem FTP dostępnym z poziomu przeglądarki WWW. Nie jest to jednak zbyt praktyczne rozwiązanie, szczególnie gdy chcemy umieszczać na stronie pliki o dużym rozmiarze, ale świetnie się ono sprawdza w wypadku małych zbiorów, takich jak pliki HTML. Spróbujmy coś takiego napisać.
13.2. Najpierw formularz
Należy zacząć od przygotowania formularza, w którym odwiedzający wskaże pliki do wysłania. W znaczniku form należy umieścić informację, że wysyłane będą dane (enctype=„multipart/form-data”); ważne jest również to, by wartość metody ustawić na post. Na końcu należy dodać komponent typu file, dzięki któremu gość wskaże plik do wysłania.
Plik formularz.html:
<form enctype="multipart/form-data" action="up.php" method="post"> |
13.3. Odbiór pliku w teorii
Po wysłaniu danych w pliku up.php dostępna będzie wielowymiarowa tablica $_FILES - pierwszym wymiarem będą nazwy pól file z formularza, a drugim następujące dane o wysłanym pliku:
name - oryginalna nazwa pliku (taka jaka u użytkownika),
tmp_name - tymczasowa nazwa pliku (użyta zostanie do skopiowania do folderu docelowego),
size - wielkość w bajtach,
type - typ MIME pliku (np. text/html),
error - (dodane w PHP 4.2) zwraca kod błędu, o ile taki wystąpił.
13.4. Kody błędów
nie wystąpił błąd - plik wysłany poprawnie,
wielkość pliku przekracza wartość maksymalną określoną w dyrektywie upload_max_filesize,
wielkość pliku przekracza wartość maksymalną określoną w polu MAX_FILE_SIZE formularza,
plik został wysłany częściowo,
żaden plik nie został wysłany.
Wyjaśnić należy chyba tylko błąd numer 2. W formularzu, z którego wysyłane będą pliki, można umieścić pole typu hidden o nazwie MAX_FILE_SIZE, gdzie należy podać maksymalną wielkość pliku do wysłania. Dla przykładu:
<input type="hidden" name="MAX_FILE_SIZE" value="30000" /> |
MAX_FILE_SIZE zależne jest od przeglądarki i nie można na nim polegać w stu procentach. Na przykład wczesne wersje Firefoksa nic sobie nie robiły z obecności takiego pola i pozwalały wysłać plik. PHP sprawdza jednak wielkość pliku i wyświetla błąd nr 2.
Przyszedł czas na zbiór up.php - dzięki niemu plik jest odbierany i zapisywany na serwerze.
<? |
Najpierw należy sprawdzić, czy plik został na pewno wysłany przez formularz. W przeciwnym wypadku istnieje możliwość ominięcia zabezpieczeń i uruchomienia np. dowolnego skryptu PHP. Jeśli plik nie został wysłany, pokazywany jest błąd. Następnie sprawdzana jest wielkość pliku, która na poniższym przykładzie nie może przekroczyć 1 MB - 1073741824 bajtów. Jeśli jego wielkość jest większa, pokazywany jest błąd. Jeżeli nie, to plik zostaje przeniesiony na właściwe miejsce i wypisywane jest potwierdzenie, że operacja przebiegła pomyślnie.
Skrypt, który odbiera plik, powinien zawierać kod określający, co stanie się z wysłanym plikiem. Możemy więc usunąć pliki za duże lub za małe. Dla przykładu:
if ($_FILES['plik']['size'] > 1073741824 |
lub odebrać tylko pliki graficzne:
if ($_FILES['plik']['type']=="image/jpeg" |
Pamiętajmy, że od PHP 4.2.0 możemy używać funkcji $_FILES['plik']['error'], aby sprawdzić, co poszło nie tak.
Jeśli podczas uploadu plików odkryjemy, że tablica $_FILES jest pusta, to oznacza, iż wielkość przesyłanego pliku przekracza wielkość ustawioną w dyrektywie post_max_size pliku php.ini.
13.5. Upload wielu plików
Jeśli potrzebujemy wysłać więcej niż jeden plik z formularza, możemy się posłużyć jedną z dwóch metod: nadać każdemu komponentowi file inną nazwę lub wykorzystać tablicę. Oto zmodyfikowany plik formularz.html:
<form enctype="multipart/form-data" action="up.php" method="post"> |
A oto up.php po drobnych przeróbkach:
<? |
14. Sesje
14.1. Wstęp do sesji
Dzięki sesjom możemy przechowywać pewne dane (takie jak identyfikator użytkownika czy jego login) podczas następujących po sobie wywołań strony. Działa to podobnie jak ciasteczka bez ustawionego czasu wygaśnięcia (expire) - przy czym dostęp do danych znika przy wylogowaniu się (dzięki specjalnemu przyciskowi na stronie) lub zamknięciu wszystkich okien przeglądarki. Sesje od ciastek odróżnia również to, że wszystkie dane są przechowywane nie u klienta, ale na serwerze. Na komputerze gościa trzymany jest jedynie identyfikator sesji, który znajduje się w ciasteczku lub przekazywany jest przez adres strony metodą GET.
reklama
Sesje rozpoczynamy, uruchamiając na stronie funkcję session_start(). Sprawdza ona, czy nie istnieje już rozpoczęta sesja. Jeśli tak, to pobiera identyfikator sesji z URL lub z ciastka i odtwarza wszystkie zmienne przechowywane w sesji, a jeżeli nie, to tworzy nową sesję i nadaje unikatowy identyfikator. Dostęp do zmiennych sesyjnych odbywa się poprzez obecną w PHP w wersji od 4.0.6 tablicę superglobalną $_SESSION. Dla przykładu:
<? |
Jeśli nie potrzebujemy już danej zmiennej zapisanej w sesji, używamy funkcji unset(), a zostanie ona „wymazana” z sesji. Dla przykładu:
<? |
Jak już wspomnieliśmy, ID sesji może być przekazane na dwa sposoby: za pomocą ciastka lub URL-u. Jako że niektóre przeglądarki mogą nie zaakceptować ciasteczek, nie należy na nich polegać w 100%. Trzeba wówczas wstawić też ID sesji do adresu strony. PHP może to zrobić sam - jeśli był kompilowany z opcją--enable-trans-sid - ale jeżeli tak się nie stało, należy ręcznie umieścić ID w adresie. Dla przykładu:
<a href="jakasstronka.php?<?=SID?>">Idź dalej</a> |
Te dwie metody mają podobne działanie, chociaż pierwsza wydaje się łatwiejsza w zapisie. Tej pierwszej można jednak użyć tylko wtedy, gdy została włączona możliwość używania krótkich tagów. Dlatego pisząc skrypty pod kątem serwera, którego konfiguracji nie znamy, używajmy tej drugiej metody.
15. Dynamiczna grafika
15.1. Jak to działa?
Dzięki użyciu obecnej domyślnie w PHP biblioteki GD istnieje możliwość dynamicznego tworzenia plików graficznych. Grafika taka jest tworzona przez parser PHP, a następnie wysyłana do przeglądarki tak jak zwykły plik graficzny. Dzięki GD można utworzyć grafikę w różnych formatach, m.in. JPG, GIF, WBMP i PNG, przy czym zalecane jest używanie właśnie PNG, który ostatnio zaczyna wypierać GIF-y z Sieci.
reklama
15.2. Podstawy
Dynamiczną grafikę wstawia się do dokumentu tradycyjnie, używając znacznika <img>. Jedyną różnicą jest to, że atrybut src wskazuje na plik z rozszerzeniem PHP. Możliwe jest nawet uruchamianie skryptu tworzącego grafikę z parametrami podanymi jako zmienne GET. Oto, jak należy wstawić przykładowy obrazek do dokumentu:
<? |
Najważniejsze jest ustawienie Content-type w nagłówku, tak aby przeglądarka mogła odpowiednio zinterpretować plik. Dla przykładu:
<? |
W zależności od założonego typu pliku należy ustawić odpowiedni Content-type na image/png, image/gif lub image/jpeg. Następnie należy utworzyć nowy, pusty obrazek za pomocą funkcji imagecreate(). Zwraca ona uchwyt do obrazka, coś na wzór uchwytu do pliku funkcji fopen(). Jako parametry tej funkcji trzeba podać wysokość i szerokość obrazka. Dla przykładu:
$img=imagecreate(200,200); |
Można też utworzyć nowy obrazek na podstawie wzorca za pomocą funkcji imagecreatefrompng(). Jest to bardzo dobra metoda do tworzenia np. przycisków na stronie. Wystarczy utworzyć jeden obrazek z tłem i później stworzyć tylko skrypt wstawiający tekst z parametru GET na gotowe tło. Dla przykładu:
$img=imagecreatefrompng("buttony/podklad1.png"); |
Po zakończeniu tworzenia obrazka trzeba go wysłać do przeglądarki. Służą do tego funkcje imagepng(), imagejpeg(), imagegif() i imagewbmp(). Pobierają one dwa argumenty. Jako pierwszy należy podać wskaźnik do obrazka, a drugi (opcjonalny) to nazwa pliku (używamy go w momencie, gdy chcemy zapisać obrazek na serwerze).
W nazwach kilku funkcji obsługi grafiki występuje również format pliku, np. imagecreatefrompng czy imagepng. Oznacza to, że funkcja ta służy do obsługi danego formatu pliku. Do obsługi innych formatów służą inne funkcje, z innymi nazwami, np. imagecreatefromjpeg czy imagegif. Należy o tym pamiętać i podczas tworzenia obrazka trzymać się zawsze jednego formatu. Tworząc cały serwis, najlepiej tworzyć pliki graficzne w jednym wybranym formacie, chociaż najbardziej przyszłościowym wydaje się właśnie PNG.
15.3. Pierwsze rysunki - deklaracja kolorów
Jeśli mamy już gotowy plik, warto teraz coś w nim narysować. Najpierw jednak należy zadeklarować kolory, które będą użyte podczas malowania. Do deklarowania koloru służy funkcja imagecolorallocate(), która pobiera cztery argumenty. Należy podać kolejno zmienną-obiekt z obrazkiem oraz wartości składowe: czerwoną, zieloną i niebieską wybranego koloru (od 0 do 225). Funkcja zwraca zmienną-identyfikator koloru. Dla przykładu:
<? |
15.4. Wypełnianie
Do wypełniania zwartych powierzchni służy funkcja imagefill(). Należy podać cztery argumenty, zmienną id obrazka, współrzędną początkową x (left), współrzędną początkową y (top) oraz id koloru. Dla przykładu:
<? |
15.5. Linie
Aby narysować linię, należy użyć funkcji imageline(). Argumenty, które należy podać, to imageline(obrazek, x_poczatkowe, y_poczatkowe, x_koncowe, y_koncowe, kolor). Na rysunku obok widać narysowaną linię i opisane współrzędne. Dla przykładu:
<? |
15.6. Kwadraty
Aby narysować kwadrat, należy użyć funkcji imagerectangle(). Argumenty, które podajemy, to imagerectangle(obrazek, x_poczatkowe, y_poczatkowe, x_koncowe, y_koncowe, kolor), przy czym x_początkowe i y_poczatkowe to współrzędne lewego górnego wierzchołka kwadratu, a x_koncowe i y_koncowe to współrzedne prawego dolnego wierzchołka. Istnieje też funkcja imagefilledrectangle() (te same argumenty), rysująca wypełniony kwadrat. Dla przykładu:
<? |
15.7. Elipsy
Do rysowania elipsy należy użyć funkcji imageellipse(). Argumenty, które podajemy, to imageellipse(obrazek, x_srodka, y_srodka, x_szerokosc, y_wysokosc, kolor). Istnieje też funkcja imagefilledellipse() (te same argumenty), rysująca wypełnioną elipsę. Dla przykładu:
<? |
15.8. Kształty bliżej nieokreślone
Jeśli musimy narysować nieregularny kształt, należy się posłużyć funkcją imagepolygon(). Argumenty, które podajemy, to imagepolygon(obrazek, tablica_wierzcholkow, ilosc_wierzcholkow, kolor). Tablica wierzchołków to tablica przygotowana według poniższego wzorca:
<? |
Pamiętajmy, żeby zmienna liczba_wierzchołkow miała taką samą wartość jak liczba, którą zadeklarowaliśmy w tablicy. W przeciwnym wypadku wystąpi błąd. Oczywiście, tak jak w innych sytuacjach, istnieje też funkcja tworzącą wypełniony wielobok - imagefilledpolygon(). Efekt taki jak na obrazku (biały wielobok z pomarańczowym obrysem) uzyskaliśmy, wywołując dwa razy tworzenie wieloboku o tych samych wierzchołkach: raz białego z wypełnieniem, a drugi raz pomarańczowego. Dla przykładu:
<? |
15.9. Łuki
Schemat działania imagearc()
i kontynuacja 'malowanki':
Aby narysować część okręgu, należy posłużyć się funkcją imagearc(). Argumenty, które podajemy, to imagearc(obrazek, x_srodka, y_srodka, szerokosc, wysokosc, kat_poczatka, kat_konca, kolor). Łuk jest zawsze rysowany od poziomu (jak na schemacie) zgodnie z ruchem wskazówek zegara. Dla przykładu:
<? |
Łuki wypełnione
IMG_ARC_PIE IMG_ARC_CHORD IMG_ARC_NOFILL
IMG_ARC_EDGED IMG_ARC_EDGED+IMG_ARC_NOFILL
W poprzednich funkcjach, żeby otrzymać figurę wypełnioną, wystarczyło zmienić nazwę funkcji, dodając filled. Aby narysować wypełniony łuk, należy się również posłużyć funkcją imagefilledarc(). Oprócz parametrów opisanych przy imagearc() musimy również na końcu dodać jeszcze styl wypełnienia. Cztery dostępne style to:
IMG_ARC_PIE - tworzy wypełniony łuk, połączony ze środkiem okręgu,
IMG_ARC_CHORD - tworzy wypełniony trójkąt, początek i koniec łuku są połączone prostą,
IMG_ARC_NOFILL - tworzy sam łuk bez wypełnienia,
IMG_ARC_EDGED - użyty pojedynczo wygląda tak samo jak IMG_ARC_PIE.
Dla przykładu:
<? |
Style można łączyć operatorem + (tworząc w ten sposób nowe style). Najlepszym przykładem na to jest połączenie IMG_ARC_NOFILL oraz IMG_ARC_EDGED, dzięki któremu otrzymujemy sam łuk i linie łączące jego końce ze środkiem (bez wypełnienia). Warto też samemu eksperymentować z różnymi kombinacjami stylów, które dają czasem dosyć ciekawe efekty.
15.10. Napisy
Do dodawania do obrazka napisów służy kilka funkcji. Pierwsza z nich to imagechar(). Dodaje ona do obrazka tylko jeden znak. Jej argumenty to imagechar(obrazek, wielkosc, x_poczatkowe, y_poczatkowe, znak, kolor). Wielkość to cyfra od 1 do 5 - 1 to najmniejsza, 5 to największa. Dla przykładu:
<? |
Istnieje też druga funkcja dodająca po jednym znaku do obrazka. To imagecharup(). Pobiera ona te same parametry, a różni się od poprzedniej tylko tym, że rysuje znak pionowo.
15.11. Ciąg znaków
Aby dodać jakiś tekst do obrazka, nie trzeba bawić się w dodawanie po kolei każdego znaku. Wystarczy uzyć funkcji imagestring(). Parametry, które podajemy, są takie same jak w wypadku imagechar(), tylko zamiast pojedynczego znaku podaje się cały ciąg. Dla przykładu:
<? |
Aby dodać tekst pionowo, wystarczy (podobnie jak w wypadku jednego znaku) użyć funkcji imagestringup().
15.11. Styl ciągu znaków
Domyślna czcionka w imagestring() nie jest zbyt ciekawa. Czasem zachodzi potrzeba wypisania czegoś bardziej ciekawym fontem. Z pomocą przychodzi wtedy funkcja imagettftext(), dzięki której możemy tworzyć napisy pisane dowolną czcionką True Type. Oto argumenty, które trzeba podać do funkcji:
imagettftext(obrazek, wielkosc, |
Wielkość to tym razem nie liczba od 1 do 5, a liczba od 5 do 150 reprezentująca wielkość w pikselach, taką jaką znamy z np. Worda. Kąt to kąt nachylenia tekstu. Wyrażenie 0 stopni to tekst pisany normalnie - poziomo. Tym razem jednak tekst jest obracany o dany kąt przeciwnie do ruchu wskazówek zegara. Zmienne x_poczatkowe i y_poczatkowe to współrzędne lewego (dolnego) wierzchołka tekstu (a nie lewego górnego, tak jak w imagestring()!). W parametrze plik_z_czcionka należy zaś podać adres do pliku .TTF z czcionką True Type. Czcionki True Type to czcionki używane w systemie - wystarczy skopiować taki plik z folderu C:\WINDOWS\FONTS i wgrać go na własne konto ze stroną. Dla przykładu:
<? |
15.12. Licznik wyświetlający grafikę
Pokażemy teraz, jak utworzyć plik licznik.php pobierający liczbę odwiedzin z parametru wizyty i wyświetlający graficznie liczbę odwiedzin. Najpierw należy ustawić odpowiednią wartość Content-type. Później kopiujemy zawartość zmiennej wizyty z tablicy _GET do zmiennej $wizyty, a w zmiennej $dl zapisujemy długość ciągu zmiennej $wizyty. Kolejno tworzymy obrazek o odpowiedniej szerokości (liczba cyfr*20) i definiujemy kolory. Pokrywamy tło na czarno i w pętli for wyświetlamy po kolei każdą cyferkę, używając funkcji imagettftext(). Na koniec wysyłamy gotowy obrazek, używając imagepng(). Dla przykładu:
<?php |
Aby teraz wstawić to do dokumentu, należy użyć znacznika <img>. Dla przykładu:
<img src="licznik.php?wizyty=12345" /> |
a tam, gdzie jest wpisane 12345, wpisać nazwę zmiennej z liczbą do wyświetlenia.
16. Referencje
16.1. Kilka słów o referencjach
Referencje pozwalają na utworzenie dwóch zmiennych o tej samej wartości i odwołujących się do jednego miejsca w pamięci. Jest to rozwiązanie problemu dublowania pamięci podczas procesu zwykłego przypisania (poniżej pokazujemy przypisanie i referencję). Dla przykładu:
<? |
W referencji podczas zmiany wartości zmiennej $b zmienia się też $a i na odwrót, podczas gdy po zwykłym przypisaniu zmienne $a i $b mogą przyjmować inne wartości.
16.2. Zalety referencji
Kolejnym plusem referencji jest możliwość odwoływania się do zmiennych globalnych w funkcji bez użycia słowa global. Dla przykładu:
<? |
Po takiej operacji wartość zmiennej $a będzie wynosiła 6. Pomimo że w funkcji zmienna $zmienna nie jest globalna, to jest ona referencją do zmiennej $a i obie odwołują się do tej samej wartości.
16.3. Koniec referencji
Czasem zachodzi potrzeba usunięcia referencji. Poniższy kod może zostać uruchomiony bez obawy o wartość zmiennej $b, ponieważ niszczona jest właśnie referencja - dowiązanie zmiennej do jej wartości, a nie jej zawartość, która dalej zostaje dostępna poprzez $b. Dla przykładu:
<? |
17. Obsługa wyjątków
17.1. Nowa obsługa błędów
W PHP5 dodano obsługę błędów podobną do tej np. z Javy, czyli bazującą na wyjątkach. Opiera się ona na trzech słowach kluczowych: try, catch i throw. Obsługa wyjątków zapisana jest w klasie Exception. Dzięki takiej obsłudze można zapisać błędy do logów albo wyświetlić wszystkie naraz na końcu działania skryptu. Dla przykładu:
reklama
<? |
W powyższym przykładzie zadeklarowaliśmy funkcję dziel, która (jak łatwo się domyślić) służy do dzielenia dwóch liczb całkowitych przez siebie. Pobiera ona dwa argumenty (liczby) i jeśli drugi z nich wynosi zero, zwraca błąd. Ale to nie jest po prostu błąd typu echo „błąd!”.
W przykładzie w bloku try zamykamy taki kod, który może zwrócić błąd (w naszym wypadku wywołanie funkcji dziel(), która może wygenerować wyjątek). Zaraz po try jest catch, w którym decydujemy, co mamy zrobić z wyjątkiem (o ile wystąpił). W zwykłym nawiasie (po catch) podajemy nazwę klasy obsługi wyjątków i zmienną, która stanie się obiektem tej klasy.
17.2. Rozbudowa klasy Exception
Klasa Exception przedstawia się następująco (za php.net):
<? |
Klasę Exception można rozbudować o własne metody lub nadpisać już w niej istniejące (można nadpisać __construct() i __toString()). Jeśli nadpisujemy oryginalny konstruktor klasy Exception, powinniśmy wywołać parent::__construct(), aby być pewnym, że wszystkie zmienne zostały poprawnie przydzielone. Oto przykład pokazujący, jak można rozbudować klasę Exception:
<? |
Teraz przerabiamy kod z powyższego przykładu, ale korzystamy z klasy extendedException:
<? |
Powyższy kod wyświetli następujący błąd:
Błąd to: niedozwolone dzielenie przez zero
Wystąpił w linijce 9
i w pliku /var/www/kurs/kurs.php
17.3. Metoda getTrace() klasy Exception
Na zakończenie tego rozdziału powiedzmy jeszcze kilka słów na temat metody getTrace(). Zwraca ona bardzo rozbudowane statystyki dotyczące błędu w postaci wielowymiarowej tablicy asocjacyjnej. Pokażmy za jej pomocą statystyki błędu w dzieleniu przez 0, wyświetlone przy użyciu funkcji print_r($e->getTrace()).
Array |
18. Bezpieczeństwo skryptów
Jeden odpowiednio wykorzystany przez hakera błąd w naszym skrypcie może pozwolić na odczytanie haseł użytkowników bazy danych czy zniszczenie całej struktury plików na serwerze. Jeśli nie chcemy, aby tak się stało i nasz serwis został zaatakowany po dwóch miesiącach żmudnego programowania, stosujmy się do poniższych rad.
18.1. Include i require - ich niebezpieczeństwa
reklama
Najbardziej niebezpieczne są funkcje include() oraz require(), gdy są użyte w nieodpowiedni sposób. W skrypcie najczęściej zawarty jest taki oto kod:
<? |
Teraz wystarczy, że (przy ustawieniu safe_mode na off - zazwyczaj tak właśnie jest) wywołamy adres index.php?file=/etc/passwd i... nazwa plików mówi sama za siebie - na serwerze unikowym wyświetli się plik z hasłami użytkowników. Aby zachować podstawowy poziom bezpieczeństwa, należy zrobić coś takiego:
<? |
Wtedy rozszerzenie będzie na pewno .php i plik będzie „includowany” z foldera ze skryptem. Nie jest to jednak rozwiązanie najlepsze, więc dobrze jest w takim wypadku korzystać ze switch. Dla przykładu:
<? |
18.2. Konfiguracja php.ini
W poprzedniej części wspomnieliśmy o trybie safe_mode. Jest to specjalna dyrektywa ustawiana w pliku php.ini (konfiguracja środowiska PHP na serwerze), która określa, czy PHP ma być uruchamiane w trybie bezpiecznym czy nie. Jeśli tylko mamy dostęp do tego pliku, warto ustawić tryb safe_mode na on. Jeśli safe_mode jest włączony, to użytkownik nie ma dostępu do plików, których nie jest właścicielem (tak więc problem tego nieszczęsnego /etc/passwd jest rozwiązany - nikt nie odczyta haseł z serwera).
Druga dyrektywa to open_basedir - określa ona folder, powyżej którego w drzewie folderów nie mamy dostępu. Jeżeli więc ustawione jest np. /var/www/users, to skrypt nie będzie miał dostępu np do /var/www. Najlepiej jest mieć te dwie dyrektywy ustawione (włączone), a jeśli nie jest to możliwe, to należy włączyć safe_mode.
18.3. Dane od użytkowników
Najbardziej zagrożonymi na ataki są te fragmenty skryptów, które operują na danych wprowadzonych przez użytkownika w formularzach lub przekazywanych metodą $_GET. Niezbędnym minimum jest w takim wypadku sprawdzenie, czy typ danych jest zgodny z tym, którego oczekujemy.
Jeśli czekamy na liczbę całkowitą, aby wykorzystać ją np. do wygenerowania zapytania do bazy danych, ważne jest, aby była to właśnie liczba, a nie ciąg tekstu, który może nam poważnie namieszać w bazie danych (atak SQL Injection). W tym wypadku należy daną - pobraną z formularza lub przesłaną za pomocą GET - rzutować do oczekiwanego typu zmiennej. Dla przykładu:
<? |
19. Baza danych MySQL
19.1. Wstęp
Użycie bazy danych to dobra alternatywa wobec plików, zwłaszcza przy budowaniu dużych serwisów czy złożonych statystyk. Pobieranie i zapisywania informacji w bazach danych opiera się na wysyłaniu do serwera bazy zapytań zapisywanych w języku SQL (Structured Query Language) zawartych w kodzie PHP, na które serwer odpowiada, pobierając z bazy odpowiednie dane i wysyłając je do nas. Zrozumienie tego na pewno ułatwi poniższy schemat:
reklama
Klient wysyła do serwera zapytanie o stronę WWW,
Serwer WWW wysyła do parsera kod PHP,
Parser wysyła do serwera baz danych zapytanie o jakieś dane,
Serwer baz zwraca dane, które są używane dalej w skrypcie,
Parser wysyła gotowy kod HTML do serwera WWW,
Serwer WWW wysyła kod HTML do przeglądarki klienta.
Przy pisaniu kodu PHP z użyciem baz danych trzeba pamiętać, że jeśli serwer PHP nie znajduje się (fizycznie) na tym samym serwerze (czyli nie ma możliwości odwołania się do niego poprzez localhost), tylko np. w innej części Internetu, może to znacznie zwolnić pracę skryptu. Podczas naszych standardowych testów po uruchomieniu strony z połączeniem do serwera bazy MySQL na innym hoście czas generowania strony wyniósł około 2,5 sekundy, a podczas gdy baza znajdowała się na serwerze lokalnym, nie trwało to nawet 0,01 sekundy.
19.2. Struktura bazy
Schemat obrazuje strukturę bazy danych. Najważniejszym elementem jest oczywiście sama baza - zazwyczaj jedna przydzielana jest dla każdego użytkownika, chociaż na serwerach komercyjnych dostaje się czasem nawet i dziesięć baz. Ingerować w bazy (tworzyć, usuwać) może zazwyczaj tylko administrator.
Kolejnym elementem są tabele - to są dopiero struktury przechowujące dane. Są one dowolnie modyfikowane przez użytkownika i może ich być dowolna liczba, bo ograniczenia są zazwyczaj nakładane przez firmy hostingowe na wielkość całej bazy, a nie na liczbę tabel.
Aby ułatwić naukę obsługi bazy MySQL-a i tworzenia własnych przykładów, we wszystkich przykładach tworzona będzie i rozbudowywana baza danych fikcyjnych uczniów jakiejś klasy oraz skrypty ją obsługujące.
19.3. Połączenie z bazą
Przed wykonywaniem operacji na bazie danych należy się z nią połączyć. Trzeba użyć funkcji mysql_connect(host[:port], nazwa użytkownika, hasło). Funkcja ta łączy się z serwerem podanym jako argument host. Opcjonalnie, jeśli MySQL pracuje na innym porcie niż 3306, należy też to podać. Dla przykładu:
<? |
Zmienna $sql podana na początku to uchwyt (handle) do połączenia z bazą. Ponownie potrzebny będzie tylko na końcu wykonywania skryptu, aby rozłączyć się z bazą:
<? |
Jeśli chcemy utworzyć duży serwis, korzystający z bazy i często odświeżany, warto połączyć się z bazą funkcją mysql_pconnect (permanent connect - stałe połączenie), dzięki któremu nie trzeba się za każdym razem łączyć z bazą. Wszystkie argumenty są te same. Występuje tutaj tylko jedna różnica: połączenia pconnect nie trzeba zamykać na końcu skryptu funkcją mysql_close.
19.4. Język SQL
Z bazą „kontaktujemy się” za pomocą zapytań. Są to polecenia pisane w języku SQL (bardzo proste) wysyłane dzięki funkcji mysql_query, która zwraca zmienną z wynikami zapytania. Najczęściej używane tutaj nazwy zmiennych są widoczne na przykładzie, ale oczywiście możemy ustalić swoje własne. Dla przykładu:
<? |
19.5. Pierwsze operacje, nowa baza
Jeśli mamy dostęp do serwera, możemy sobie założyć bazę. Jedyną sprawą, o której należy pamiętać, jest wywołanie funkcji mysql_create_db(nazwa), która tworzy bazę o nazwie podanej w argumencie. Po utworzeniu i przed rozpoczęciem pracy należy pamiętać, aby też wybrać bazę, z którą chcemy pracować. Robimy to za pomocą polecenia mysql_select_db(nazwa). Dla przykładu:
<? |
19.6. Nowe tabele
Gdy założyliśmy już bazę danych, kolejnym krokiem jest utworzenie tabel. W tym celu budujemy zapytanie o następującej składni:
"CREATE TABLE nazwa (nazwa1 typ1, nazwa2 typ2, |
Możemy teraz utworzyć tabelę według podanego powyżej zapytania.
"CREATE TABLE uczniowie (id char(2) NOT NULL |
Stworzona zostanie tabela o nazwie uczniowie z polami id, imie, nazwisko, urodzony, przy czym id będzie kluczem podstawowym, czyli indeksem, i nie będzie się mógł powtarzać. Oprócz tego, jeśli dodamy NOT NULL, to klucz nie będzie mógł być pusty. Opcja AUTO_INCREMENT sprawia natomiast, że jeśli nie podamy wartości id do wpisania, to zostanie ona automatycznie wpisania (wartością stanie się wartość poprzedniego rekordu id podniesiona o jeden).
Dostępnych jest wiele rodzajów pól - oto kilka najważniejszych:
char(x) - ciąg znaków o maksymalnej długości podanej jako parametr x (x<256),
longtext - ciąg znaków o praktycznie nieograniczonej długości,
date - data w formacie YYYY-MM-DD,
year - rok; jeśli zostanie podany zły, jego wartość zmieni się na 0000,
time - przechowuje czas w formacie timestamp,
tinyint, smallint, mediumint, int, bigint - liczby całkowite,
longblob - przechowuje dane binarne (np. obrazki) o praktycznie nieograniczonej wielkości,
enum, set - podobne jak „radio” w formularzach, do wyboru są tylko opcje zadeklarowane uprzednio przy tworzeniu bazy (np. tak/nie).
19.7. Wstawianie danych
Aby wstawić jakieś dane do tabeli, należy posłużyć się instrukcją INSERT. Jej schemat jest następujący:
"INSERT INTO nazwa_tabeli (pole1, pole2, pole3) |
Jako pole1, pole2 itd. wpisujemy nazwy pól, które chcemy wypełnić, a w wart_pola1 itd. w odpowiedniej kolejności wartości do dodania. Dla przykładu:
"INSERT INTO uczniowie (imie, nazwisko, dziennik) |
W powyższym wypadku wartość pola id zostanie ustalona na 1, ponieważ jest to pierwszy rekord w tabeli. Jeśli wstawialibyśmy to samo jeszcze raz, to miałby on cały czas wartość id o jeden większą od poprzedniej. Wstawmy do bazy kilka pojedynczych rekordów z danymi uczniów:
<? |
19.8. Wybieranie konkretnych rekordów
Aby wybrać z bazy danych jakieś dane, należy posłużyć się operatorem SELECT. Jego składnia to:
SELECT pole1, pole2, pole_n FROM nazwa_tabeli |
Jest to dość zawiłe, dlatego teraz po kolei wytłumaczymy całe zapytanie.
pole1, pole2, pole_n - określają nazwy pól, które serwer baz ma wysłać w wyniku. Jeśli chce się otrzymać wszystkie, wystarczy wpisać * (gwiazdkę),
FROM nazwa_tabeli - to chyba najprostszy fragment; określa nazwę tabeli, z której mają być wybrane rekordy,
WHERE warunek1 AND warunek2 - to warunek (warunki), według których serwer ma przeszukiwać bazę. Można nie podać ich wcale i wtedy wynik będzie zawierał wszystkie rekordy z tabeli. Warunki można łączyć operatorami AND oraz OR, a także brać w nawiasy (tak jak w IF w PHP),
ORDER BY nazwa_klucza rodzaj_sortowania - określa, według jakiego klucza posortowane mają być wyniki i w jakiej kolejności. Dostępne są dwa rodzaje sortowania: ASC (rosnące) i DESC (malejące),
LIMIT klucz_poczatkowy, ilosc_rekordów - określa, ile wyników ma być zwróconych. Warto pamiętać, że ilosc_rekordow pokazuje, ile ma być zwróconych rekordów od klucz_początkowy, a nie jest to id klucza końcowego (częsty błąd).
Na schemacie pokazujemy przykład użycia LIMIT. W wynikach jest 16 rekordów, potrzebne są rekordy od 3 do 14. Ważne jest, aby się nie pomylić i w ilosc_rekordow podać całkowitą liczbę potrzebnych rekordów, a nie id ostatniego (tak jak w większości baz danych czy na adresowaniu komórek w Excelu). Dla przykładu:
<? |
W warunkach do przeszukiwania mogą też wystąpić takie operatory, jak IN lub BETWEEN. Dla przykładu:
<? |
Zastępcą znanego z instrukcji warunkowych wykrzyknika jest NOT. Można go użyć zarówno przed pojedynczą instrukcją, jak i przed całym nawiasem. Dla przykładu:
<? |
Nie zawsze da się dokładnie porównać dwa ciągi znaków. Czasem należy posłużyć się operatorem LIKE. Porównuje on konkretną wartość ze wzorcem. Zaznaczmy przy tym, że % (procent) zastępuje w wyrażeniu dowolną liczbę znaków, a _ (podkreślenie) zastępuje dokładnie jeden znak. Dla przykładu:
<? |
19.9. Modyfikacja rekordów
Czasem zachodzi potrzeba poprawienia jakiegoś rekordu. Błąd może być wynikiem nieuwagi przy wprowadzaniu danych, ale możemy też chcieć zmienić adres klienta w bazie danych sklepu internetowego. Służy do tego polecenie UPDATE. Jego składnia to:
UPDATE nazwa_tabeli SET pole1='xyz', |
Przyjrzyjmy się bliżej temu zapytaniu:
nazwa_tabeli - to po prostu nazwa tabeli, w której ma nastąpić zamiana rekordów,
SET pole1='xyz', pole2 = 'abc', polen = 'bcd' - określa pola i wartości, które mają być do nich przydzielone,
WHERE warunki - określa, które rekordy mają być modyfikowane. W wypadku gdy nie podamy warunku w WHERE, modyfikacji ulegają wszystkie rekordy w tabeli.
Dla przykładu:
<? |
19.10. Usuwanie rekordów
Do usuwania jednego, kilku określonych rekordów lub zawartości całej tabeli służy DELETE. Jego składnia to:
DELETE FROM nazwa_tabeli WHERE warunki |
Oznaczenia są takie same jak w poprzednich poleceniach i nie trzeba ich jeszcze raz opisywać. Warto zaś zaznaczyć, że jeśli niepodany zostanie warunek WHERE, to tabela zostanie wyczyszczona. Dla przykładu:
<? |
19.11. Funkcje do obsługi MySQL-a
W PHP istnieje wiele funkcji do kontaktu z bazą danych MySQL i obsługi zapytań. Podstawowe już znamy:
mysql_connect - łączy z bazą danych,
mysql_pconnect - łączy trwale z bazą danych,
mysql_create_db - tworzy bazę danych,
mysql_select_db - wybiera bazę danych,
mysql_close - kończy połączenie z bazą danych,
mysql_query - wysyła zapytanie do bazy danych.
19.12. mysql_num_rows()
Funkcja mysql_num_rows(rezultat) zwraca liczbę rekordów z wyniku zapytania skierowanego do serwera bazy. Poniższy przykład wyświetla liczę rekordów w tabeli uczniowie:
<? |
19.13. mysql_fetch_array()
Funkcja mysql_fetch_array(rezultat [,typ]) zwraca przy każdym wywołaniu kolejny wiersz z wyniku zapytania w postaci tablicy zwykłej lub asocjacyjnej (lub jednej i drugiej). Typ tablicy zależy właśnie od parametru typ. Może on przybrać wartość MYSQL_ASSOC (zwraca wynik w postaci tablicy asocjacyjnej), MYSQL_NUM (w postaci zwykłej tablicy) albo (domyślnie) MYSQL_BOTH (tablicy indeksowanej asocjacyjnie i numerycznie). Dla przykładu:
<? |
19.14. mysql_insert_id()
Funkcja mysql_insert_id() zwraca ID wygenerowane dla pola z własnością AUTO_INCREMENT. Uwaga! Funkcja mysql_insert_id() zwróci 0, gdy rekord był dodawany do tabeli bez pola AUTO_INCREMENT. Dla przykładu:
<? |
19.15. mysql_result()
mysql_result(rezultat ,wiersz [,kolumna])- Bardzo przydatna funkcja, gdy trzeba się odwołać do konkretnego pola w konkretnym rzędzie wyniku. Wystarczy podać jako pierwszy argument zmienną z rezultatem zapytania, jako drugi wiersz, a jako trzeci (opcjonalnie)pole w danym wierszu (domyślne to 0).
<? |
19.16. mysql_error()
Funkcja mysql_error() pokazuje treść ostatniego błędu wygenerowanego przez serwer MySQL. Warto wywołać tę funkcję po zapytaniu do bazy, które powoduje błędy. Dla przykładu:
<? |
wyświetli coś w stylu „#1146 - Table 'baza.ucnziowie' doesn't exist”.
19.17. Wyświetlanie wyniku zapytania
Częstym błędem początkującego programisty jest próba wykonania następującego kodu:
echo $res; |
Niestety, $res jest niejako obiektem zawierającym zgrupowane dane, a więc za pomocą echo nie da się ich bezpośrednio wyświetlić. Istnieją dwie podstawowe metody przeglądania danych z zapytania do MySQL-a. Pierwsza - wiersz po wierszu - i druga - bezpośrednio odwołując się do danego wiersza lub kolumny.
1. Pętla while i mysql_fetch_array
Dla przykładu:
<? |
Przy każdej iteracji pętli zmienna $row staje się czteroelementową tablicą. Dzięki ustawionemu MYSQL_BOTH do rekordów mamy dostęp zarówno poprzez nazwy indeksów (np. config_value), jak i poprzez kolejne cyfry (w danym wypadku config_name to 0, a config_value to 1). Ważne jest to, by wybrać wygodniejszy dla siebie sposób, pamiętając o wadach każdego z nich (MYSQL_ASSOC to więcej pisania, przy MYSQL_NUM natomiast podczas zmiany zapytania może się „posypać” cały skrypt).
2. Funkcja mysql_result()
Metoda ta jest dobra przy pobieraniu pojedynczego elementu z dużego zapytania do bazy. Jej zaletą jest to, że nie trzeba przechodzić przez całą bazę, wadą jest natomiast konieczność znajomości dokładnej lokalizacji wyniku w zapytaniu (współrzędne wiersz i kolumna).
Dla przykładu:
<? |
Do administrowania swoją bazą danych, a w szczególności całym serwerem i wszystkimi bazami, polecamy używania darmowego skryptu phpMyAdmin. Pozwala on na bardzo szybki i sprawny nadzór nad bazami, tabelami i użytkownikami baz.
20. Smarty
Smarty to system szablonów przygotowany dla PHP. Jego głównym zadaniem jest oddzielenie logiki skryptu (obliczeń, pobierania danych z bazy) od treści wyświetlanych na stronie. Po pierwsze, zwiększa to czytelność samego kodu - bardzo denerwujące jest, gdy fragmenty kodu są poprzedzielane blokami echo wyświetlającymi kilka znaków - a ponadto ułatwia pisanie aplikacji w zespołach. Załóżmy, że nad stroną gazety internetowej pracują dwie osoby: programista i grafik. Jeśli grafik chce zmienić layout strony wyświetlającej artykuły, nie musi zmieniać jej kodu. Wystarczy, że zmieni szablon, i gotowe. I sprawa odwrotna: programista, chcąc zmienić skrypt, nie musi się bać, że precyzyjnie zaprojektowana strona przygotowana przez grafika się rozsypie - zmienia kod PHP, nie ingerując przy tym w layout.
20.1. Instalacja
reklama
Aby zainstalować Smarty, trzeba przekopiować folder libs z archiwum smarty do folderu ze stroną. Następnie należy założyć cztery foldery: templates, templates_c, cache i configs, a później w pliku, gdzie chcemy wykorzystać Smarty, „includujemy” klasę libs/Smarty.class.php (uwaga na wielkość liter w systemach uniksowych!). Na końcu wystarczy utworzyć nowy obiekt na bazie klasy Smarty. Dla przykładu:
<? |
System szablonów nie może się obyć bez… szablonu. Tworzymy więc pierwszy szablon i zapisujemy go w folderze templates. Dla przykładu:
Plik index.tpl:
Moje imię to: |
Przypisujemy nową zmienną szablonu poprzez metodę assign() klasy Smarty. Pobiera ona dwa argumenty: nazwę zmiennej i jej wartość. Następnie wyświetlamy szablon za pomocą display(). Dla przykładu:
<? |
Po uruchomieniu pliku index.php zobaczymy następującą treść:
Moje imię to: |
20.2. Składnia Smarty
Domyślnie wszystkie tagi zamykają się w znakach { } (nawiasy klamrowe). Wszystko, co znajduje się poza nimi, wyświetlane jest bez zmian, tagi są natomiast parsowane przez Smarty.
20.3. Komentarze
Komentarze mieszczą się pomiędzy tagami {* i *}. Służą do organizowania struktury szablonu i nie są później w żaden sposób widoczne w kodzie gotowej strony. Dla przykładu:
{* Pokazuje imię ze zmiennej z pliku index.php *} |
20.4. Zmienne
Zmienne są oznaczane, podobnie jak w PHP, symbolem dolara. Można je wyświetlać na kilka sposobów:
{$zmienna} - wartość zwykłej zmiennej,
{$zmienna[66]} - element tablicy o indeksach numerycznych,
{$zmienna.pole} - element tablicy asocjacyjnej (w PHP: $zmienna['pole']),
{$obiekt->zmienna} - zmienna obiektu $obiekt,
{$obiekt->funkcja()} - metoda obiektu $obiekt,
{$zmienna[pole]} - poprawne tylko w pętlach {section},
{#foo#} - zmienna konfiguracyjna,
{$smarty.config.foo} -zmienna konfiguracyjna (inny zapis).
20.5. Funkcje
Każdy tag Smarty albo wyświetla jakąś zmienną, albo uruchamia funkcję. Zmienne już znamy - teraz czas na funkcje. Dla przykładu:
{config_load file="kolorki.conf"} |
Są dwa rodzaje funkcji: wbudowane (np. if), których nie można modyfikować, i funkcje modyfikowalne, które są dodawane poprzez system plug-inów (wtyczek). Możemy je łatwo modyfikować, dostosowywać do swoich potrzeb i tworzyć nowe. Są to np. html_options czy html_select_date.
20.6. Inne delimitery tagów Smarty
Delimiterem domyślnie są znaki: { oraz }. Problem zaczyna się, gdy chcemy używać w szablonie np. JavaScriptu, który też korzysta z nawiasów klamrowych. Aby zmienić domyślne delimitery, podmieńmy zmienne left_delimiter i right_delimiter klasy Smarty. Dla przykładu:
<? |
plik index.tpl:
{* Inny delimiter *} |
BIBLIGRAFIA
Kurs PHP, Leszek Krupiński, http://www.leon.w-wa.pl/texts/kurs/.
Kurs PHP, Grzegorz 'Ygreg' Plebański, http://www.ygreg.com/pokaz.php/php0.
Manual PHP, http://php.net.pl/manual/pl/index.php.
Kurs PHP na Wikibooks, http://pl.wikibooks.org/wiki/PHP.