Artur Świderek
2001-12-01
Spis treści
Czym jest PHP?
PHP A SERWER WWW
PHP może być zainstalowany w dwojaki sposób. Pierwszy, najbardziej popularny, to instalacja jako moduł serwera, np. Apache'a. Wówczas skrypt PHP jest wykonywany na prawach użytkownika, który jest właścicielem Apache'a - zwykle nobody. Drugi, rzadziej stosowany sposób to instalacja PHP jako programu CGI. Wówczas skrypty PHP umieszczane są w katalogu ze skryptami CGI (najczęściej jest to katalog cgi-bin). Należy również pamiętać, taki skrypt jest pełnoprawnym programem CGI (Common ateway Interface) i musi mieć odpowiednie uprawnienia (755, czyli -rwxr-xr-x) oraz w pierwszej linii pliku ścieżkę do interpretera języka.
Instalacja
Aby móc testować skrypty musimy mieć zainstalowany serwer www i interpreter PHP. Pliki instalacyjne do obydwu programów można znaleźć na stronie PHP.pl w dziale download. Po ściągnięciu instalujemy Apache'a w domyślnym katalogu, potem w zależności od wersji interpretera PHP rozpakowywujemy go do katalogu c:\php albo instalujemy do tegoż katalogu. Podczas instalacji zaznaczamy wszystkie możliwe rozszerzenia PHP, tj. .php, .php3 i .phtml. Jeżeli miałeś wersję spakowaną to musisz jeszcze zamienić nazwę pliku c:\php\php.ini-dist na c:\php\php.ini. Wyżej wymieniony plik jest plikiem konfiguracyjnym interpretera, jednak do zwykłego korzystania z interpretera nie jest potrzebna specjalna konfiguracji, dlatego nie będziemy nic w nim zmieniać. Po instalacji serwera i interpretera możesz spróbować uruchomić serwer. Powinien albo krótko po uruchomieniu wyłączyć się, albo po uruchomieniu przeglądarki i próbie wejścia na adres http://127.0.0.1/ powinien wyświetlić się błąd "Strony nie znaleziono" albo coś w tym stylu. Aby serwer działał musimy go odpowiednio skonfigurować.
Konfiguracja
Plikiem konfiguracyjnym Apache'a, który będziemy zmieniać jest httpd.conf, znajdujący się w katalogu conf w katalogu gdzie zainstalowano Apache'a (domyślnie c:\Program Files\Apache Group\Apache\). Otwórz go pod Notatnikiem. Wyszukaj w nim linii z ServerName. Zamień ją na ServerName 127.0.0.1 (może być także localhost). Jeżeli przed ServerName występuje znaczek # (haszyk) to usuń go. W ten sposób ustaliliśmy nazwę serwera, przez którą będziemy mogli wywoływać nasze strony i skrypty. Teraz można uruchomić Apache'a i sprawdzić czy działa. Uruchom Apache.exe, potem przeglądarkę i wejdź na strone http://127.0.0.1/. Powinna pojawić się strona powitalna Apache'a (jeżeli masz starszą wersję Apache'a może wyświetlić się spis plików w katalogu htdocs).
Teraz dodamy kilka rozszerzeń indexu. Standardowo po wywołaniu http://127.0.0.1/ wywoływana jest strona http://127.0.0.1/index.html. Jeżeli takowej nie ma pokazuje się spis zawartości katalogu. Dzięki tej linijce, którą za chwilę zamienimy, będzie (jeżeli nie ma index.html) sprawdzało czy istnieją i uruchamiały index.php i index.php3. Znajdź w pliku konfiguracyjnym linijkę DirectoryIndex. Jeżeli występuje przed nią znak # usuń go. Teraz zamień tę linię na DirectoryIndex index.html index.php index.php3. Serwer sprawdza czy index istnieje w kolejności takiej jak zapisane jest to w pliku konfiguracyjnym, czyli u nas to będzie wyglądało tak:
Serwer sprawdza czy istnieje index.html
Jeżeli istnieje to wyświetla jego zawartość
Jeśli nie istnieje to sprawdza czy istnieje index.php
Jeżeli istnieje to wykonuje skrypt i wyświetla wyniki
Jeśli nie sprawdza czy istnieje index.php3
Jeżeli tak to wykonuje skrypt i wyświetla jego wyniki
Jeśli nie pokazuje zawartość katalogu htdocs
Teraz czas na dodanie trzech linii do pliku httpd.conf (czyli konfiguracyjnego), informujących serwer www o ścieżce dostępu do interpretera PHP i jego rozszerzeniach. Oto te trzy linie:
ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php3 .php3 .php .phtml
Action application/x-httpd-php3 "/php/php.exe"
Można je wkleić w każdym miejscu pliku. Od tej pory można się już bawić w pisanie skryptów i je testować
Używanie
Wszystkie pliki ze stronami i skryptami przechowywane są w katalogu htdocs w katalogu domyślnym Apache'a. Aby uruchomić skrypt musisz przegrać go do tego katalogu, uruchomić Apache'a i w pasku adresu wpisac http://127.0.0.1/url gdzie url to adres pliku wewnątrz, np.: http://127.0.0.1/katalog/skrypt.php gdzie katalog to folder podrzędny do htdocs (czyli domyślnie adres do tego katalogu to c:\Program Files\Apache Group\Apache\htdocs\katalog), a skrypt.php to nazwa skryptu razem z rozszerzeniem. Jeżeli w katalogu htdocs mamy całą witrynę to możemy ją uruchomić z adresu http://127.0.0.1/katalog, gdzie katalog to folder w którym znajduje się cała witryna. I to wszystko!
ROZSZERZENIA PLIKÓW PHP
Pliki stron WWW zawierających skrypty PHP mogą mieć różne rozszerzenia w zależności od konfiguracji serwera. Najczęściej stosowane to: *.php, *.php3, *.phtml. Jeżeli chcesz, aby pliki PHP miały także inne rozszerzenia, musisz w pliku httpd.conf (lub srm.conf) wpisać w sekcji AddType następującą linię:
AddType application/x-httpd-php .<nowe rozszerzenie> |
a następnie, aby plik index z nowym rozszerzeniem był traktowany jako domyślny plik katalogu, w sekcji DirectoryIndex dopisać:
DirectoryIndex index.<nowe rozszerzenie> |
UMIESZCZANIE SKRYPTÓW PHP W KODZIE HTML
Skrypty PHP (obecnie Hypertext Preprocessor) wykonywane są po stronie serwera, ale umieszczane bezpośrednio w kodzie strony. Serwer interpretuje kod PHP i przekazuje przeglądarce stronę WWW bez wstawek PHP. Kod PHP umieszczany jest na stronie za pomocą następujących znaczników:
<?php i ?>
<? i ?>
<script language=php> i </script>
<% i %>
Drugi typ znaczników, nazywany Short Tags (krótkie znaczniki), dostępny jest, jeżli w pliku konfiguracyjnym PHP (c:\apache\php\php.ini w win32) włączona jest opcja short_open_tag:
short_open_tag = On |
lub po wywołaniu funkcji short_tags().
Czwarty typ znaczników pochodzi z języka ASP i nie jest dostępny w standardowej konfiguracji PHP. Aby go uaktywnić należy włączyć następującą opcję:
asp_tags = On |
PRZYKŁADOWY SKRYPT PHP
W celu przedstawienia podstawowych cech PHP zostanie zaprezentowany i omówiony przykładowy skrypt odpowiedzialny za wyświetlenie na stronie aktualnej daty.
<html> |
Wynikiem działania tego skryptu będzie:
<html> |
Zwrócony tekst zastąpi znaczniki skryptu (<? i ?>) wraz z umieszczonym między nimi kodem i komentarzami.
Najważniejsze elementy języka
W powyższym przykładzie pobieramy do zmiennej aktualną datę. Jak widać w PHP zmiennych nie trzeba deklarować, a one same rozpoczynają się znakiem $.
Zapis date("d-m-Y") oznacza wywołanie funkcji date(), która zwraca aktualną datę w ustalonym formacie (dzień-miesiąc-rok).
Funkcja echo() odpowiedzialna jest za zwracanie tekstu podanego w nawiasie do przeglądarki. Zauważ, że jako argument funkcji został przekazany tekst umieszczony w podwójnych cudzysłowach ("), w którym znajduje się zmienna $aktualna_data. Ten rodzaj cudzysłowu mówi parserowi PHP, że ma przeszukać tekst w poszukiwaniu zmiennych (rozpoczynających się od znaku $) i zamienić je na ich wartości. Gdybyś zastosował pojedyncze cudzysłowy ('), zwrócony tekst przybrałby następującą postać:
<html> |
Widać, że teksty umieszczone w takich cudzysłowach nie sa przeszukiwane w celu znalezienia zmiennych i zostają wydrukowane dokładnie tak, jak zostały zapisane.
Komentarze
W powyższym przykładzie użyto trzech rodzajów komentarzy, które służą do oisywania fragmentów kodu i nie są interpretowane przez parser PHP i wysyłane do przeglądarki.
W PHP dostępne są komentarze w stylu języka C, C++ oraz Unix shell:
// komentarz jednoliniowy
/* komentarz
wieloliniowy */
# komentarz jednoliniowy w stylu Unix-shell
Komentarze // i # mogą być używane w oddzielnych liniach kodu:
<? |
oraz bezpośrednio po linii kodu zakończonej średnikiem (;):
<? |
Zasady notacji
Podstawowa notacja języka PHP opiera się na następujących zasadach:
kończenia każdej linii kodu znakiem ;,
umieszczania przed nazwami zmiennych znaku $,
zapisywania w jednej linijce kodu jednej instrukcji lub wyrażenia,
nie rozróżniania wielkości liter w nazwach funkcji,
rozróżniania wielkości liter w nazwach zmiennych.
W celu zwiększenia czytelności zapisu można stosować wcięcia i komentarze.
ZMIENNE
TYPY ZMIENNYCH
W PHP nie musisz deklarować nazwy zmiennej ani jej typu przed użyciem. W trakcie wykonywania skryptu typ określi samo PHP w zależności od sytuacji w jakiej zmienna została zastosowana.
Jeżeli jest dla Ciebie istotne, aby dana zmienna była określonego typu i nie chcesz, żeby decydował o tym parser PHP, możesdz użyć do ustalenia typu zmiennej funkcji settype(). Zmienna zostanie wtedy przekonwertowana na wskazany typ. Jezeli zaś chcesz sprawdzić typ zmiennej, możesz użyć funkcji gettype() do jego odczytania.
Liczby całkowite
Liczby całkowite jako typ danych w PHP to dodatnie i ujemne liczby dziesiętne, liczby ósemkowe i szesnastkowe. Ich deklaracja wygląda następująco:
<? |
Liczby zmiennoprzecinkowe
Liczby zmiennoprzecinkowe zawierają część dziesiętną. W PHP zapisuje się je w sposób następujący:
<? |
Łańcuchy znaków
Łańcuchy znaków przechowują różnego rodzaju teksty. Są one umieszczane w cudzysłowach pojedynczych (') lub w podwójnych ("). Tylko w tej drugiej sytuacji tekst zostanie przeszukany w celu znalezienia zmiennych. Jeżeli natomiast umieścisz tekst w cudzysłowach pochylonych (`), to zostanie on potraktowany przez parser PHP jako polecenie zewnętrzne, które nalezy wykonać.
<? |
Znaki specjalne
Znaki specjalne w PHP tworzy się przez dodanie przed danym znakiem backslasha (\). Istnieją dwa typy znaków specjalnych: znaki formatujące i znaki drukowane.
Znaki formatujące to np. znak \n, który oznacza przejście do nowej linii.
<? |
Powyższy kod zwróci do przeglądarki następujący wynik:
Pierwsza liniadruga linia |
Natomiast ten:
<? |
zwróci:
Pierwsza linia |
Znaki nowej linii (\n) nie będą interpretowane przez przeglądarkę jako łamanie wiersza, w HTML-u bowiem stosuje się znacznik <br>. Wprowadzone przejścia do nowej linii będą widoczne natomiast w kodzie źródłowym strony.
Aby osiągnąć przejście do nowej linii i w kodzie strony, i w HTML-u, należy zastosować taki sposób pisania:
<? |
Pozwyższy kod zwróci do przeglądarki następujący tekst:
Pierwsza linia<br> |
Pewne znaki, na przykład $ czy " pełnią specjalne funkcje. Aby parser PHP traktował taki zapis jak normalny znak, a nie początek zmiennej czy tekstu, należy za każdym razem umieścić prze nim baskslash (\).
<? |
Kod ten zwróci:
Znak " oznacza cudzysłów |
Spróbujmy teraz napisać to samo, ale z użyciem podwójnego cudzysłowu:
<? |
Kod ten zwróci to, co poprzednio, ale ze znakiem nokej linii na końcu, ponieważ w podwójnych cudzysłowach mogliśmy użyć zanaku \n. W pojedynczych zostałby on zignorowany i wydrukowany jako normalny tekst.
Znak " oznacza cudzysłów |
Gdybyśmy nie napisali przed znakiem " backslasha, parser PHP zwróciłby komunikat:
Parse error: parse error in <lokalizacja pliku> on line <numer linii> |
Wybrane znaki specjalne:
\n - nowa linia |
Konwersje łańcuchów
Ponieważ PHP samo definiuje typy zmiennych, możliwe jest wykonywanie działań arytmetycznych na tekstach i liczbach (całkowitych lub zmiennoprzecinkowych). Łańcuch tekstowy będzie traktowany jako liczba zmiennoprzecinkowa, jeśli zawiera jeden ze znaków: -, e lub E. W innym przypadku łańcuch tekstowy będzie traktowany jako liczba całkowita. PHP spróbuje wyszukać na początku tekstu wartość numeryczną i jeśli jej nie znajdzie, podstawi wartość domyślną czyli zero (0).
<? |
Używanie stringów
Większość prac w tworzeniu stron internetowych wymaga użycia stringów, więc ich używanie oraz poprawne wykorzystanie jest bardzo ważne dla programisty PHP. Ten tutorial zacznę prostymi przykładami użycia stringów, aby następnie wejść w bardziej zaawansowane techniki wykorzystywania stringów.
W PHP stringiem jest wszystko pomiędzy cudzysłowami:
'Jestem stringiem w pojedynczym cudzysłowie' |
Parser PHP rozróżnia stringi poprzez znajdywanie par cudzysłowów. Więc, wszystkie stringi muszą zaczynać się i kończyć tym samym rodzajem cudzysłowu - pojedynczym lub podwójnym. Dla przykładu to NIE są poprawne stringi w PHP:
"Nie jestem poprawnym stringiem ponieważ mam różne cudzysłowy na poczatku i końcu' |
Tylko jeden typ cudzysłowu jest ważny przy definiowaniu stringa, pojedynczy (') lub podwójny ("). Dla przykładu, jeżeli zaczniemy stringa przy pomocy podwójnego cudzysłowu to zakończenie takiego stringa także musi być przy pomocy podwójnego cudzysłowu, inaczej parser nie uzna go jako stringa. Możesz używać pojedynczych cudzysłowów wewnątrz podwójnego I na odwrót.
Oto przykładowe poprawne stringi w PHP:
$s="Jestem 'stringiem w pojedynczym cudzysłowie' wewnątrz podwójnego cudzysłowu "; |
Sposób sprawdzenia przez PHP czy jest to string polega na przejściu od jednego cudzysłowia do drugiego identycznego. Przykładowo:
"Why doesn't "this" work?" |
|
|
|
jest widziane przez parser PHP w trzech częściach:
"Why doesn't " |
string w podwójnym cudzysłowie w którym znajduje się pojedynczy cudzysłów
this |
śmieci których parser nie potrafi zrozumieć
" work?" |
kolejny string.
Powyższy przykład próbuje umieścić podwójny cudzysłów wewnątrz stringa będącego w podwójnym cudzysłowie. Jest to problemem ponieważ parser znajduje pierwszą parę pasujących cudzysłowów i sądzi że jest to koniec naszego stringa. Aby umieścić cudzysłów wewnątrz stringa aby parser zignorował taki cudzysłów musimy użyć przed nim backslasha ( \ ). Użycie backslasha mówi PHP że cudzysłów jest częścią stringa. Oto poprawny przykład powyższego przykładu:
"Why doesn't \"that\" work?" |
Podobny problem spotykamy próbując użyć cudzysłowu pojedynczego w stringu znajdującym się w pojedynczym cudzysłowie:
'You\'d better escape your apostrophes' |
Oznacza to że backslash ma specjalne znaczenie w stringach. Zatem aby umieścić backslasha w stringu musimy jego także poprzedzić backslashem. Dla przykładu:
$file = "c:\windows\system.ini"; |
Innym sposobem na tworzenie stringów, który eliminuje potrzebę używania backslashy jest format znany jako "Here Document". Jest on przydatny przy dużych ilościach tekstu. Zacznij Here Document ze znacznikiem <<< a za nim umieść identyfikator który nie pojawi się w Twoim tekście. Identyfikator ten posłuży nam jako znacznik końca tekstu:
$head = <<<ENDH |
Łączenie stringów.
Stringi mogą być łączone poprzez operator (.).
$first_name = 'Charlie'; |
Częstą potrzebą w PHP jest tworzenie dużych stringów HTML. Przypisywanie (=) i łączenie (.) mogą być ze sobą łączone (.=) aby ułatwić sprawę.
$html = '<table>'; |
Używanie zmiennych w stringach:
Więc nie chcesz łączyć ze sobą wielu prostych stringów, PHP umożliwia Ci zastosowanie zmiennych wewnątrz podwójnego cudzysłowia. Więc oba poniższe kody dadzą ten sam rezultat $full_name:
$full_name = $first_name . ' ' . $last_name; |
Podwójne i pojedyncze cudzysłowy przy stringach są różnie rozróżniane przez PHP. Podwójne cudzysłowia są interpretowane, podczas gdy pojedyncze są traktowane dokładnie w ten sposób w jaki zostały napisane. Dla przykładu:
$foo = 2; |
Jak widać nawet backslashe nie są rozróżniane w pojedynczych cudzysłowach, pomijając \\ (wstawia backslash), i \" (wstawia podwójny lub pojedynczy cudzysłów).
Podwójne cudzysłowy powinny być używane gdy chcemy użyć zmiennej w stringu lub użyć specjalnego znaku jak \n (nowa linia).
Pojedyncze cudzysłowy powinny być używane dla wszystkich innych stringów. Skrypt używający pojedynczych cudzysłowów wykonuje się trochę szybciej ponieważ parser PHP używa stringów bezpośrednio. Podwójne cudzysłowy są wolniejsze ponieważ muszą zostać zinterpretowane przez parser.
Odwoływanie się do złożonych kombinacji zmiennych wewnątrz stringów może przynieść niespodziewane rezultaty. Więc poniższe linie zadziałają:
echo "value = $foo"; |
Ale poniższy przykład nie zadziała tak jakbyśmy się tego spodziewali:
echo "value = $a[$i][$j]"; |
Aby uniknąć potencjalnych problemów podczas używania zmiennych wewnątrz stringów, zazwyczaj najlepiej "wyrzucić" zmienne poza stringa gdy odwołujemy się do złożonych kombinacji zmiennych.
echo 'value = ' . $a[$i][$j]; |
Inną alternatywą jest umieszczanie nawiasów klamrowych na bardziej złożonych odwołaniach do zmiennych:
echo "value = {$a[$i][$j]}" |
Oznacza to oczywiście że jeżeli chcesz mieć nawiasy klamrowe wokół zmiennej podczas wyświetlania, musisz wstawić backshlasha przy otwierającej klamrze nawiasu:
$var = 3; |
Slashe i zapytania SQL
Jedną z ciekawszych rzeczy w pisaniu kodu PHP jest potrzeba częstego generowania kodu HTML oraz zapytań SQL, który jest innym rodzajem kodu aniżeli kod PHP. W wyniku tego musimy uważać na wymaganą składnię tego kodu.
Rozpatrując przypadek w którym wyszukujemy wszystkich użytkowników o nazwisku O'Keefe. Zapytanie powinno wyglądać tak:
select * from users where last_name = 'O\'Keefe' |
Zauważ jak SQL wymaga backslasha przy cudzysłowie w nazwisku O'Keffe. PHP ma w sobie wiele funkcji które ułatwiają nam sprawę. AddSlashes($str) może być użyte do automatycznego wstawiania backslashy do stringa, funkcja ta zrobi to za nas.
$last_name = "O'Keefe"; |
Musisz wstawić pojedynczy cudzysłów na początku i końcu stringa last_name. Ten przykład używa podwójnego cudzysłowia. Poniższy przykład jest alternatywą która tworzy w ten sam sposób zapytanie:
$sql = 'select * from users where last_name = \'' . addslashes($last_name) . '\''; |
Za każdym razem gdy wstawiasz stringa do zapytania upewnij się czy wszystkie cudzysłowy zostały poprawnie wstawione. Pomyłka ta jest często robiona przez programistów PHP.
Podwójne cudzysłowy i HTML
Inaczej niż w SQLu, podwójne cudzysłowy są używane do wskazywania stringów w HTMLu. Oto dwa przykłady tworzenia linków HTML w PHP:
$html = '<a href="'.$url.'">'.$link.'</a>'; |
HTML nie obsługuje użycia slashy aby zignorować podwójny cudzysłów. Jest to główny problem podczas tworzenia ukrytych zmiennych w HTMLu oraz stałych. Najlepszym wyjściem w tej sytuacji jest użycie funkcji htmlspecialchars(), która umożliwi nam bez problemów umieszczenie danych w ukrytych polach.
Oto kod HTML dla ukrytej zmiennej, która może zawierać podwójny cudzysłów:
<input type=hidden name=var value="<?php echo htmlspecialchars($var) ?>"> |
Stringi bez użycia cudzysłowów
Możliwe jest użycie stringów w PHP bez zamykania ich w cudzysłów.
Jeżeli jest to pojedyncze słowo bez znaków interpunkcyjnych to można użyć go gdziekolwiek w kodzie gdzie normalnie używa się stringów w cudzysłowach. Działa to także dla argumentów funkcji, tablic i innych.
Oto kilka przykładów stringów bez cudzysłowów:
echo $a[apple]; // apple jest stringiem bez cudzysłowów |
Ponieważ w dzisiejszych czasach stringi bez cudzysłowów używane są do definiowania stałych, nie powinieneś używać ich jako stringów. Jeżeli przydarzy Ci się zdefiniowanie stałej o nazwie apple, przykład ten zmieni całkowicie swoje oblicze. Więc ta praktyka jest rzadko spotykana, można ją jednak czasami spotkać w starszych skryptach.
Operacje na stringach
PHP zawiera wiele funkcji do obsługi stringów. Najlepszym miejscem do zapoznania się z nimi jest rozdział "Strings" w manualu do PHP. Poniżej przedstawiłem kilka problemów oraz rozwiązań związanych z operacjami na stringach.
String PHP jest tablicą znaków z początkowym indeksem zerowym. Oznacza to że pierwsza litera stringa ma pozycję zerową w tablicy. Wszystkie funkcje operujące na stringach używają zera jako indeksu do pierwszej litery w stringu.
W języku C, wszystkie porównania stringów robione były za pomocą funkcji strcmp(). Ta funkcja jest dostępna także w PHP, jednak możemy mimo wszystko porównywać stringi bezpośrednio ze sobą. poniższe przykłady są sobie równoważne:
$str1 = 'abc'; |
substr() umożliwia Tobie wyciągnięcie części stringa "podstringa (ang. Substring)". Używa się go poprzez podanie pozycji początkowej oraz długości wyciąganej części:
$str = substr('abcdef', 2, 3); // cde |
lub jako offset od końca stringa:
$str = substr('abcdef', -2); // ef |
Możesz nawet dać offset od końca stringa zamiast podawać długość:
$str = substr('abcdef', 2, -2); // cd |
Czasami nie znamy dokładnej pozycji "podstringa" w stringu. W tym przypadku, szukamy mniejszego stringa w większym. Funkcje: strpos(), strstr(), strrchr() and strrpos().
$i = strpos('przykładowy string do testowania', 'st'); // $i = 10 |
Najprostszą metodą do formatowania stringów jest użycie funkcji sprintf(). Funkcja ta jest identyczna do tej występującej w języku C pod tą samą nazwą. Pobiera jako parametry format stringa oraz kilka argumentów. Formatowanie stringa umożliwia wyświetlenie zmiennych w danym formacie nawet z możliwością ustalenia precyzji dla liczb. Każde (%xxx) jest zamieniane z formatowaną wartość danego argumentu. Oto kilka przykładów użycia tej funkcji:
$s = sprintf("%04d-%02d-%02d", 1999, 8, 4); // 1999-08-04 |
Tablice
Tablice, pobobnie jak zmienne, służą do przechowywania danych. Są bardziej rozbudowaną strukturą danych. Odwołujemy się do nich za pomocą nazwy tablicy i indeksu liczbowego bądź tekstowego. Tablice jako struktury są tematem następnego rozdziału (rozdział o tablicach).
<? |
Ostatnia linia skryptu zwraca następujący kod:
element pierwszy o indeksie 0<br> |
Klasy
Klasy służą do przechowywania zmiennych i funkcji w jednym obiekcie o określonym identyfikatorze.
<? |
Powyższy kod tworzy klasę o nazwie 'koszyk'. Można na niej wykonać dwie czynności: dodaj daną ilość jabłek oraz odczytać ile jest ich już w koszyku. Spójrzmy zatem na przykład korzystania z takiej klasy:
<? |
Ten kod zwróci ilość jabłek w koszyku, czyli:
Masz 8 jabłek w koszyku |
NAZWY ZMIENNYCH
W PHP nazwy zmiennych tworzy się poprzez napisanie znaku dolara ($) oraz nazwy określającej zmienną. Na nazwę zmiennej mogą składać się wszystkie litery i cyfry oraz znaki podkreślenia. Zmienna nie może rozpoczynać się od cyfry, lecz może od znaku podkreślenia (_). W nazwach zmiennych rozróżniana jest wielkość liter, dlatego $a i $A to zupełnie różne zmienne z innymi danymi, a nawet z danymi innego typu.
<? |
TWORZENIE ZMIENNYCH
Ponieważ w PHP nie trzeba deklarować zmiennej przed jej użyciem, stworzenie zmiennej następuje w momencie przypisania jej wartości. Wartości dopisuje się za pomocą operatora przypisania (=). Po lewej stronie stoi nazwa zmiennej, po prawej - wartość liczbowa, tekst lub funkcja.
<? |
Możliwe jest także dopisywanie wartości zmiennej przez referencję, co sygnalizuje znak & przed znakiem $ zmiennej. Takie przypisanie warości do nowej zmiennej oznacza, że jej wartość wskazuje na wartość oryginalnej zmiennej. Zmiana wartości jednej ze zmiennych odnosi się również do drugiej.
<? |
Powyższy kod zwraca:
Kolejny tekst |
Jak widać zmienna $a ma taką samą wartość, jak zmienna $b
OPERATORY DLA ZMIENNYCH
W tej części kursu zostaną zaprezentowane operatory potrzebne do działań na zmiennych. Operatory logiczne zostały natomiast opisane w dziale Instrukcje warunkowe.
Opratory arytmetyczne
+ Dodawanie |
Przykład dodawania, odejmowania, mnożenia, dzielenia i wyliczania reszty z dzielenia:
<? |
Powyższy przykład zwraca:
8 |
Operatory przypisania
Operator |
Opis |
= |
Liczba stojąca po lewej stronie operatora przyjmuje wartość liczby stojącej po prawej stronie operatora |
|
|
+= |
Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą sumą jej samej i liczby stojącej po prawej stronie operatora |
|
|
-= |
Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą różnicą jej samej i liczby stojącej po prawej stronie operatora |
|
|
*= |
Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą iloczynem jej samej i liczby stojącej po prawej stronie operatora |
|
|
/= |
Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą ilorazem jej samej i liczby stojącej po prawej stronie operatora |
|
|
%= |
Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą resztą z dzielenia (modulo) jej samej i liczby stojącej po prawej stronie operatora |
Przykład:
<? |
Powyższy przykład zwraca:
5 |
Operatory inkrementacji/dekrementacji
Operator |
Opis |
++ |
Inkrementacja zmiennej (powiększenie jej wartości o 1) |
-- |
Dekrementacja zmiennej (pomniejszenie jej wartości o 1) |
<? |
Powyższy przykład zwraca:
3 |
Operatory łańcuchowe
Operator |
Opis |
. |
Połączenie dwóch ciągów tekstowych |
.= |
Dodanie do tekstu stojącego po lewej stronie operatora tekstu stojącego po prawej stronie |
<? |
kawałek |
ZASIĘG ZMIENNYCH
Tworzone w skryptach PHP zmienne nie są widoczne w funkcjach. Funkcje mają swoje zmienne, które mogą mieć nazwy takie, jak inne zmienne użyte wcześniej przed deklaracją funkcji, ale będą miały swoje wartości i nie będą dostępne w skrypcie.
Jeżeli chcesz, aby zmienna stworzona w skrypcie była widoczna w funkcji musisz użyć instrukcji global.
<? |
Powyższy kod w załozeniu miał wydrukować liczbę 5, ale tego nie robi, ponieważ zmienna $zmienna nie jest zmienna globalną, więc nie jest widoczna dla funkcji druk(). Aby osiągnąć cel, należałoby napisać:
<? |
ZMIENNE ZMIENNYCH
Zmienne zmiennych, nazywane czasem zmiennymi symbolicznymi mają nazwy utworzone z wartości innych zmiennych.
<? |
Powyższy kod zwraca:
test zmiennych... |
Spójrzmy na inny przykład:
<? |
Powyższy przykład zwraca zawartość zmiennej :
Działa! |
ZMIENNE FORMULARZY
Zmienne formularzy to zmienne utworzone na podstawie wysłanego formularza. Jeżeli formularz zawierał pole tekstowe o nazwie imie_kota i użytkownik wpisał do niego imię Mruczek, to w skrypcie dostępna jest zmienna imie_kota o wartości 'Mruczek'
Oto przykładowy formularz:
<form action=imie_kota.php method=post> |
I skrypt PHP drukujący podane imię kota:
<? |
Formularze HTML można wysyłać przy użyciu dwu metod: POST i GET. Przy użyciu metody POST dane wysyłane są na standardowym urządzeniu wejściowym - STDIN. Ta metoda nadaje się do przesyłania większych porcji informacji (np. z pól TEXTAREA). W przypadku użycia metody GET dane z formularza oddzielone za pomocą ?, & oraz = wyyłane są w adresie URL. Dane tak przesłane ą oczywiście dostępne w zmiennych o odpowiednich nazwach, ale są również dostępne w zmiennej $QUERY_STRING w postaci:
Parametr1=wartosc1&Parametr2=wartosc2 |
STAŁE
W PHP możesz również definiować stałe za pomocą funkcji define(). Wartość stałych jest definiowana raz i nie może być zmieniana. Nazwa stałej jest zwyczajowo pisana wielkimi literami, ale nie jest to konieczne.
<? |
Powyższy kod zwraca:
wartość stałej... |
ZMIENNE PREDEFINIOWANE
Zmienne predefiniowane są tworzone przez PHP automatycznie i zawierają różne informacje na temat serwera, skryptu itp. Pełną listę tych zmiennych uzyskasz wywołując skrypt:
<? |
Zmienne środowiskowe
Zmienne środowiskowe pozwalają na dowiedzenie się o wielu różnych parametrach pracy serwera czy też klienta. Można z nich odczytać informacje np. o systemie operacyjnym, przeglądarce i adresie IP odwiedzającego, a równierz nazwę serwera WWW i port połączenia.
Czasami chcemy wiedzieć coś więcej na temat osób odwiedzających nasze strony, jednak nawet rozbudowana ankieta nie wystarczy, aby zaspokoić naszą ciekawość. Czasami zdarza się również, że chcemy wiedzieć coś więcej nt. serwera, z którego korzystamy, a nasz administrator jest zbyt zajęty, żeby odpowiadać nam na podstawowe pytania. W obu tych przypadkach przychodzą nam z pomocą zmienne środowiskowe. Zmienne te zawierają specjalne informacje dotyczące konfiguracji serwera WWW czy konfiguracji PHP. Poniżej postaram się przedstawić kilkanaście wg mnie przydatnych zmiennych.
Opisy niektórych zmiennych:
$COMPUTERNAME |
Zawiera nazwę komputera, z którego korzysta osoba odwiedzająca naszą stronę |
$OS |
Zawiera nazwę systemu, z jakiego korzysta osoba odwiedzająca naszą stronę. |
$SystemDrive |
Zawiera nazwę dysku, na którym zainstalowany jest system |
$SystemRoot |
Zawiera ścieżkę miejsca zainstalowania systemu |
$SERVER_SOFTWARE |
Zawiera nazwy oprogramowania serwera WWW |
$SERVER_NAME |
Zawiera nazwę serwera |
$SERVER_PROTOCOL |
Zawiera nazwę protokołu serwera |
$SERVER_PORT |
Zawiera numer portu serwera |
$PATH_INFO |
Zawiera ścieżkę oraz nazwę uruchomionego skryptu |
$PATH_TRANSLATED |
Zawiera bezwzględną ścieżkę do uruchomionego skryptu |
$SCRIPT_NAME |
Zawiera nazwę skryptu |
$REMOTE_ADDR |
Zawiera IP osoby odwiedzającej stronę |
$REMOTE_HOST |
Zawiera nazwę hosta osoby odwiedzającej stronę |
$HTTP_REFERER |
Zawiera URL poprzedniej odwiedzonej strony |
$HTTP_USER_AGENT |
Zawiera nazwę przeglądarki, z której korzysta osoba oglądająca stronę |
Te oraz dużo więcej zmiennych wraz z bardzo przydatnymi informacjami nt. serwera i PHP możecie uzyskać tworząc prosty plik php:
<? phpinfo(); ?> |
Po uruchomieniu tego pliku waszym oczom ukaże się masa tabelek zawierających odpowiednią ilość informacji, żeby zaspokoić nawet najbardziej ciekawskich.
Wnioski:
Znając tyle zmiennych możemy z nich skorzystać na różne sposoby. Możemy po prostu zmieścić bardzo prostą informację na stronie, która informowała by z jakiej przeglądarki korzysta użytkownik, jaki jest jego adres IP oraz skąd przybywa:
Używasz przeglądarki Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98)
Twój adres IP to 195.117.166.146
Przybyłeś tutaj ze strony http://php.bajo.pl/artykuly.php?id=2
TABLICE
TABLICE JEDNOWYMIAROWE
Tablice jednowymiarowe mogą przechowywać jedną kolumnę danych. Składają się z nazwy tablicy (poprzedzonej znakiem $) i indeksu podanego w nawiasach kwadratowych ([ i ]).
Tworzenie tablic
Tablice można zainicjować (utworzyć) na dwa sposoby: za pomocą funkcji array() oraz poprzez dopisanie nowego (pierwszego) elementu.
<?
$tablica = array();
?>
Powyższy kod tworzy nową tablicę, ale bez żadnego elementu. Można jednak od razu przy tworzeniu tablicy zadeklarować jej elementy:
<?
$tablica = array("element1","element2","element3");
?>
Powyższy przykład tworzy tablicę z już zadeklarowanymi elementami. Elementy oddziela się od siebie za pomocą przecinka, a łańcuchy znaków umieszcza w cudzysłowach. Natomiast jeżeli wartość liczbowa jest liczbą, nie ma potrzeby umieszczania jej w cudzysłowach:
<?
$tablica = array(1,2,3);
?>
Domyślnie pierwszy element ma indeks o wartości 0 Jeżeli chcesz, żeby tablica zaczynała się od innego indeksu, musisz użyć operatora =>.
<?
$tablica = array(1 => "element1","element2","element3");
?>
W podobny sposób możesz utworzyć tablicę z tylko niektórymi indeksami:
<?
$tablica = array(
1 => "element1",
3 => "element2",
5 => "element3"
);
?>
Powyższy przykład różni się trochę w zapisie od poprzedniego, ponieważ zastosowano w nim przejścia do nowej linii i wcięcia, ale tylko w celu zwiększenia czytelności. Nie wpływa to na naszą tablicę, zapis jest za to o wiele bardziej intuicyjny.
Aby utworzyć tablicę zawierającą indeksy tekstowe możemy również posłużyć się operatorem =>:
<?
$tablica = array(
"pole1" => "element1",
"pole2" => "element2",
"pole3" => "element3"
);
?>
Dodawanie elementów
Dodawanie nowych elementów do tablicy odbywa się poprzez napisanie nazwy tablicy i podanie numeru (indeksu) pozycji, do której chcemy dopisać nową wartość:
<?
# indeks liczbowy
$tablica[0] = "element1";
$tablica[1] = "element2";
$tablica[2] = "element3";
?>
Jeżeli dodajesz nowe pozycje do tablicy, tak jak w powyższym przykładzie, możesz uprościć nieco zapis, nie podając numerów indeksów (pisząc samo []). W takim przypadku PHP samo dodaje nowe elementy, poczynając od indeksu o wartości 0. Kolejne elementy dodawane są zawsze na końcu tablicy:
<?
# tworzenie tablicy z indeksami liczbowymi, które nie są podawane
$tablica[] = "element1";
$tablica[] = "element2";
$tablica[] = "element3";
?>
Możesz rónież dopisywać nowe elementy podając indeksy tekstowe:
<?
# indeks tekstowy
$tablica["jeden"] = "element1";
$tablica["dwa"] = "element2";
$tablica["trzy"] = "element3";
?>
Wyświetlenie danych
Odwoływanie się do tablicy jednowymiarowej wymaga napisania nazwy tablicy oraz podania w nawiasach kwadratowych indeksu elemantu. Indeks może być liczbą całkowitą lub łańcuchem znaków.
<?
# definicja tablicy
$tablica = array("element1","element2","element3");
# drukowanie elementów od 0 do 2
echo($tablica[0]);
echo($tablica[1]);
echo($tablica[2]);
?>
Powyższy przykład zwraca listę elementów tablicy:
element1
element2
element3
W podobny sposób drukuje się zawartość tablic o indeksach tekstowych.
<?
#definicja tablicy
$tablica = array(
"pole1" => "element1",
"pole2" => "element2",
"pole3" => "element3"
);
# drukowanie elementów od 'pole1' do 'pole3'
echo($tablica["pole1"]);
echo($tablica["pole2"]);
echo($tablica["pole3"]);
?>
Prowyższy przykład zwraca listę elementów tablicy:
element1
element2
element3
Spójrzmy jeszcze na taki przykład:
<?
$tablica = array(1,2,3);
echo($tablica);
?>
Co zwróci w typ przypadku funkcja echo()? Ponieważ nie został podany indeks elementu tablicy, PHP zwróci tylko nazwę typu zmiennej:
Array
PHP ma wiele funkcji działań na tablicach - od przeglądania po sortowanie. Wszystkie są szczegółowo omówione w manualu PHP na stronach http://pl.php.net.
Funkcja print_r
Funkcja print_r() jest bardzo wygodna przy debugowaniu skryptu. Drukuje ona zawartość podanej zmiennej z uwzględnieniem jej struktury.
<?
#definicja tablicy trójelementowej
# dwa indeksy tekstowe i jeden liczbowy
$tablica = array(
"pole1" => "element 1 (indeks: pole1)",
"pole2" => "element 2 (indeks: pole2)",
5 => "element 3 (indeks: 5)"
);
# wydrukowanie zawartości zmiennej
echo("<pre>");
print_r($tablica);
echo("</pre>");
?>
Powyższy przykład wydrukowania tablicy przy użyciu funkcji print_r() i znaczników <pre> i </pre> (dla zachowania czytelności kodu w przeglądarce) zwraca:
Array
(
[pole1] => element 1 (indeks: pole1)
[pole2] => element 2 (indeks: pole2)
[5] => element 3 (indeks: 5)
)
TABLICE WIELOWYMIAROWE
Tablice wielowymiarowe mogą przechowywać więcej niż jeden rząd danych. Za pomocą takiej tablicy możesz opisać tabelkę składającą się z kolumn i rzędów:
<? |
Tablice wielowymiarowe są po prostu tablicami jednowymiarowymi, w których w jednym z elementów umieszczono nie wartość liczbową czy tekstową, a inną tablicę. Tablica z powyższego przykładu ma następującą strukturę (funkcja print_r()):
Array |
Można uczynić deklarację takiej tablicy bardziej czytelną, nazywając indeksy rzędów za pomocą liter A, B, i C:
<? |
Struktura takiej tablicy wygląda podobnie, ale rzędy nazywane są odpowiednio A, B i C:
Array |
Jak widać na powyższym przykładzie w PHP można w tablicach wielowymiarowych używać zamiennie indeksów liczbowych i tekstowych. Takie podejście znacznie poprawia czytelność kodu.
Można również tworzyć tablice o większej liczbie wymiarów:
<? |
Struktura przykładowej trójwymiarowej tablicy wygląda następująco:
Array |
INSTRUKCJE WARUNKOWE
INSTRUKCJA IF
Instrukcja if wykonuje podany kod, jeżeli warunek umieszczony w nawiasach jest prawdziwy (zwraca wartość true). Podstawowa składnia warunku if wygląda następująco:
<? |
Nawias okrągły może występować bezpośrednio po słownie kluczowym if lub po spacji (tak jak w powyższym przykładzie); jest to tylko kwestia gustu programisty i czytelności kodu:
<? |
Spójrzmy zatem na przykład instrukcji, która sprawdza, czy zmienna $test jest liczbą większą od zera:
<? |
I tak powyższy kod zwróci:
Podano liczbę większą od zera |
Spójrzmy na taki przykład:
<? |
Wydawałoby się, że w przypadku niespełnienia warunku taki kod nie zwróci niczego (wartość false) albo w przypadku spełnienia wydrukuje dwie linie. Jednak jest inaczej. Linia 'Kolejna linia' zawsze zostanie wydrukowana, ponieważ przy takim zapisie nie należy do instrukcji wykonywanych zależnie od warunku. Aby możliwe było wykonanie więcej niż jednej instrukcji, po warunku należy taki kod oznaczyć jako blok instrukcji stanowiących jedną całość za pomocą nawiasów klamrowych ({ i }).
Struktura takiego bloku wygląda następująco:
{ |
Wszystko, co znajduje się pomiędzy nawiasami klamrowymi, stanowi jeden blok instrukcji. Jeżeli przy występowaniu więcej niż jednej linii kodu nie zastosowałbyś ograniczników bloku (czyli nawiasów klamrowych), w przypadku spełnienia warunku wykonywana byłaby tylko pierwsza linia kodu, a pozostałe zostałyby wydrukowane niezależnie od zadanego warunku.
Spójrzmy zatem na udoskonaloną wersję naszego przykładu:
<? |
Teraz powyższy kod nie zwróci niczego, ponieważ zmienna testowa jest mniejsza od zera. Natomiast następujący kod:
<? |
zwróci:
Podano liczbę większą od zera |
Aby zobaczyć, jak warunek if wygląda w praktyce, przypomnijmy sobie formularz do podawania imienia kota z rozdziału o zmiennych:
<form action=imie_kota.php method=post> |
Spróbujmy teraz napisać skrypt, który będzie drukował powyższy formularz, jeżeli nie podano imienia kota (lub przy wywoływaniu skryptu, jeśli zmienna jest pusta). Najpierw zbudujmy strukturę poprawnej stront HTML zawierającej formularz:
<html> |
Czas teraz na dopisanie instrukcji if, która sprawdzi, czy imie kota zostało podane i czy trzeba wydrukować formularz. Posłużmy się tutaj warunkiem $imie_kota == "":
<html> |
Powyższy przykład drukuje formularz w przypadku, kiedy imię kota nie zostało podane. Ale jak wydrukować stronę z informacją już po wysłaniu formularza? Można to zrobić w taki oto, trochę niezręczny sposób:
<html> |
Klauzula else i elseif
Klauzula else oznacza "wykonaj, jeżeli warunek nie był wykonany". To właśnie jej brakowało w poprzednim przykładzie:
<html> |
Klauzula elseif oznacza natomiast "wykonaj, jeżeli warunek nie był spełniony, oraz jeżeli...". Można w ten sposób sprawdzać podane imię kota i wykonywać różne czynności dla różnych imion:
<html> |
Powyższy przykład jest już znacznie bardziej rozbudowany. Potrafi różnie reagować na podane imiona. Taki sam efekt możesz osiągnąć stosując po klauzuli else instrukcję if:
<html> |
Zastosowany sposób zapisu jest różny przywarunkach drugim i trzecim, ale nie wpływa to na ich działanie.
Alternatywny sposób zapisu
PHP udostępnia jeszcze jeden sposób zapisu bloków w warunkach:
<? if (warunek): ?> |
Blok rozpoczyna się znakiem :, a kończy instrukcją endif.
Taki sposób zapisu może bardzo ułatwić drukowanie kodu HTML, ponieważ bez używania instrukcji echo() można go umieścić między warunkami:
<html> |
Można również zapisać powyższy kod w taki sposób:
<html> |
OPERATORY DLA WARUNKÓW
W konstruowaniu warunków przydają się bardzo operatory porówania i logiczne:
Operatory porównania
== równość |
<? |
Operatory logiczne
and, && równość |
<? |
Jak widać, kolejne warunki umieszcza się w nawiasach okrągłych i łączy za pomocą operatorów logicznych.
INSTRUKCJA SWITCH
Instrukcja switch może zastąpić w naszym przykładzie z imieniem kota blok instrukcji if-elseif-else:
<html> |
Po każdym bloku występuje instrukcja break, która mówi PHP, że ma przerwać sprawdzanie warunków po wykonaniu powyższych linii kodu (które zostaną wykonane tylko wtedy, gdy zawartość zmiennej podanej w switch() odpowiada wartości podanej w klauzuli case). Gdyby instrukcja break nie została podana, PHP po znalezieniu prawdziwej wartości wykonałoby resztę kodu, nie zwracając uwagi na wartości zawarte w case.
Istnieje również instrukcja exit, która w odróżnieniu od break kończy działanie skryptu.
Klauzula default pełni taką samą funkcję jak else w instrukcji if, oznacza inną wartość, nie podaną wcześniej. Klauzula ta nie musi być podawana zawsze, podobnie jak if w instrukcji warunkowej.
Alternatywny sposób zapisu
Instrukcja switch może być również zapisana w następujący sposób:
<html> |
Blok instrukcji switch zostaje w tym przypadku otwarty za pomocą znaku :, a zakończony instrukcją endswitch.
PĘTLE
INSTRUKCJA WHILE
Podstawowa struktura pętli while przedstawia się następująco:
<? |
Pętla while jest wykonywana aż do momentu, gdy warunek przyjmie wartość false. Jeżeli warunek już na samym pocątku nie był prwdziwy, pętla nie zostanie wykonana ani razu. Spójrzmy na taki przykład:
<? |
Pętla zostanie wykonana 5 razy. Na początku zmienna $i ma wartość 1. Jeżeli warunek jest prawdziwy linia zostaje wydrukowana i następuje inkrementacja zmiennej, po czym sytuacja się powtarza. Przykład ten zwróci:
Licznik ma wartość: 1 |
Zbudujmy teraz taki warunek, który od razu nie jest spełniony:
<? |
Kod ten niczego nie zwróci, ponieważ warunek od początku nie był prawdziwy i pętla nie została wykonana ani razu.
Jeżeli chcemy zapisać więcej linii kodu wewnątrz pętli, kod należy umieścić w obrębie nawiasów klamrowych:
<? |
Co zwróci:
Wartość licznika: 2 |
Ponieważ inkrementacja zmiennej i zapisanie jej wartości następuje przed wydrukowaniem, licznik drukowany jest od wartości 2 do 6.
Alternatywny sposób zapisu
PHP udostępnia jeszcze jeden sposób zapisu takiej pętli:
<? |
Blok instrukcji while zostaje w tym przypadku otwarty za ponicą znaku :, a zakończony instrukcją endwhile.
INSTRUKCJA DO..WHILE
Podstawowa struktura pętli do..while przedstawia się następująco:
<? |
Pętla do..while jest wykonywana aż do momentu, gdy warunek przyjmie wartość false. Natomiast nawet jeżeli warunek od początku nie był prawdziwy, pętla zostanie wykonana jeden raz. Spójrzmy na taki przykład:
<? |
Pętla zostanie wykonana 5 razy. Na początku zmienna ma wartość b>1. Linia zostaje wydrukowana i następuje inkrementacja zmiennej. Jeżeli warunek nadal jest prawdziwy, sytuacja się powtarza. Przykład ten zwróci:
Licznik ma wartość: 1 |
Zbudujmy teraz taki warunek, który od razu nie jest spełniony:
<? |
Jeśli użyliśmy pętli while, kod niczego nie zwracał, ale w tym przykładzie otrzymamy następujący wynik:
Licznik ma wartość: 6 |
Zostaje wydrukowana jedna linia, ponieważ sprawdzanie warunku wykonania pętli następuje dopiero po wykonaniu instrukcji. PHP wykonuje kod jeden raz i dopiero potem sprawdza warunek.
INSTRUKCJA FOR
Podstawowa struktura pętli for przedstawia się następująco:
<? |
Na początku zostaje wykonane wyrażenie licznik. Może to być na przykład przypisanie wartości początkowej zmiennej licznika. Następnie zostaje speŁniony warunek i jeżeli jest on spełniony, następuje wykonanie pętli. Jeżeli warunek zwróci wartość false, pętla zostaje przerwana. Wyrażenie inkrementacja lub dekrementacja służy do zwiększania lub zmniejszania wartości licznika. Pętla for oferuje podobne możliwości jak pętla while.
Spójrzmy na przykład zastosowania pętli for:
<? |
Taka konstrukcja zwraca:
Licznik ma wartość: 1 |
Podobnie jak w pętli while czy w instrukcjach if blok kodu pętli umieszcza się wewnątrz nawiasów klamrowych:
<? |
Możliwe jest również stworzenie pętli o zmniejszającym się liczniku od wartości 5 do 1:
<? |
Taka pętla zwraca:
Licznik ma wartość: 5 |
Alternatywny sposób zapisu
PHP udostępnia jeszcze jeden sposób zapisu takiej pętli:
<? |
Blok instrukcji for zostaje w tym przypadku otwarty za pomocą znaku :, a zakończony instrukcją endfor.
INSTRUKCJA FOREACH
Podstawowa struktura pętli foreach przedstawia się następująco:
<? |
<? |
Ta konstrukcja pozwala na łatwe przeglądanie tablic. Jeśli w kodzie znajduje się więcej niż jedna linia, umieszcza się go w nawiasach klamrowych jako blok instrukcji. Spójrzmy na przykład:
<? |
Powyższy przykład zwraca:
Zawartość tablicy: |
Możliwe jest również wydrukowanie liczbowego bądź tekstowego indeksu danego elementu. Do tego celu wykorzystamy operator => przy deklaracji pętli:
<? |
Powyższy kod podaje już indeksy drukowanego elementu:
Zawartość tablicy: |
Alternatywny sposób zapisu
PHP udostępnia jeszcze jeden sposób zapisu tej pętli:
<? |
Blok instrukcji foreach zostaje w tym przypadku otwarty za pomocą znaku :, a zakończony instrukcją endswitch
INSTRUKCJA BREAK
Jak już wiesz, instrukcja break kończy wykonywanie pętli lub instrukcji switch. Przykład ilustruje użycie instrukcji break wewnątrz pętli for, dla której nie podano warunku:
<? |
Taki kod zwraca dokładnie to samo, co poprzenie pętle:
Licznik ma wartość: 1 |
Instrukcja break może być także używana wewnątrz pętli while.
INSTRUKCJA BREAK
Jak już wiesz, instrukcja break kończy wykonywanie pętli lub instrukcji switch. Przykład ilustruje użycie instrukcji break wewnątrz pętli for, dla której nie podano warunku:
<? |
Taki kod zwraca dokładnie to samo, co poprzenie pętle:
Licznik ma wartość: 1 |
Instrukcja break może być także używana wewnątrz pętli while.
FUNKCJE
TWORZENIE FUNKCJI
W PHP funkcje deklaruje się za pomocą słowa kluczowego function. Następnie podaje się, po spacji oddzielającej nazwę funkcji oraz w nawiasach okrągłych zmienne argumentów. Kod instrukcji funkcji umieszcza się wewnątrz bloku wyznaczonego przez nawiasy klamrowe:
<? |
ARGUMENTY FUNKCJI
Aby funkcja mogła operować na konkretnych danych, trzeba je jakoś do niej przekazać. Właśnie do tego służą argumenty. Przy deklarowaniu funkcji jest to lista zmiennych oddzielonych przecinkami. Przy wywołaniu funkcji podaje się natomiast listę wartości, również oddzielonych przecinkami. PHP wspiera przekazywanie argumentów przez wartość i przez referencje. Dostępne są równiez domyślne wartości argumentów i zmienne liczba argumentów.
Przekazywanie argumentów przez wartość
Typowym sposobem przekazywania argumentów jest ich przekazywanie przez wartość. Spójrzmy na przykład:
<? |
Wywołanie tej funkcji wygląda następująco:
<? |
Powyższe wywołania funkcji test() zwracają:
Podano następujące argumenty: |
Przekazywanie argumentów przez referencję
Domyślnie zmiana wartości argumentu wewnątrz funkcji nie wpływa na wartość argumentu na zewnątrz funkcji. Dzięki referencji możliwa jest zmiana zachowania funkcji. Spójrzmy na taki przykład:
<? |
Wywołanie tej funkcji wygląda następująco:
<? |
Powyższe wywołanie funkcji test() zwraca:
To jest piękny tekst [ten tekst dodała funkcja test()] |
Spójrzmy jeszcze na taki przykład:
<? |
Wywołanie funkcji test():
<? |
Powyższe wywołanie funkcji zwracają:
To jest piękny tekst |
Domyślne wartości argumentów
PHP wspiera obsługę domyślnych wartości argumentów, które nie muszą być wtedy podawane:
<? |
Oto różne wywołanie tej funkcji:
<? |
Powyższe wywołania funkcji test() zwracają:
Podano następujące argumenty: jeden |
Jak widać z powyższego przykładu, drugi argument ma przypisaną wartość domyślną, która jest używana w przypadku niepodania tego argumentu
Argumenty domyślne muszą być umieszczone na końcu aby było możliwe ich niepodawanie. Spójrzmy na przykład zadeklarowanie argumentów (zwróć uwagę na ich kolejność):
<? |
Oto różne wywołania tej funkcji:
<? |
Powyższe wywołania funkcji test() zwracają:
Podano następujące argumenty: |
Zwrócone ostrzeżenie świadczy o niepodaniu wymaganego argumentu wywołania funkcji.
Przy tego typu deklaracjach argumentów bardzo przydają się funkcje func_num_args(), func_get_arg() oraz func_get_args().
func_num_args()
Funkcja ta zwraca liczbę podanych argumentów wywołania funkcji:
<? |
Przykład wywołania funkcji:
<? |
Wynik działania funkcji:
Podano 5 argumentów! |
func_get_arg
Funkcja ta zwraca wartość podanego argumentu wywołania funkcji:
<? |
Przykład wywołania funkcji:
<? |
Wynik działania funkcji:
Trzeci argument: 3 |
func_get_args
Funkcja ta zwraca tablicę argumentów wywołania funkcji:
<? |
Przykład wywołania funkcji:
<? |
Wynik działania funkcji:
Podano następujące argumenty: |
ARGUMENTY FUNKCJI
Aby funkcja mogła operować na konkretnych danych, trzeba je jakoś do niej przekazać. Właśnie do tego służą argumenty. Przy deklarowaniu funkcji jest to lista zmiennych oddzielonych przecinkami. Przy wywołaniu funkcji podaje się natomiast listę wartości, również oddzielonych przecinkami. PHP wspiera przekazywanie argumentów przez wartość i przez referencje. Dostępne są równiez domyślne wartości argumentów i zmienne liczba argumentów.
Przekazywanie argumentów przez wartość
Typowym sposobem przekazywania argumentów jest ich przekazywanie przez wartość. Spójrzmy na przykład:
<? |
Wywołanie tej funkcji wygląda następująco:
<? |
Powyższe wywołania funkcji test() zwracają:
Podano następujące argumenty: |
Przekazywanie argumentów przez referencję
Domyślnie zmiana wartości argumentu wewnątrz funkcji nie wpływa na wartość argumentu na zewnątrz funkcji. Dzięki referencji możliwa jest zmiana zachowania funkcji. Spójrzmy na taki przykład:
<? |
Wywołanie tej funkcji wygląda następująco:
<? |
Powyższe wywołanie funkcji test() zwraca:
To jest piękny tekst [ten tekst dodała funkcja test()] |
Spójrzmy jeszcze na taki przykład:
<? |
Wywołanie funkcji test():
<? |
Powyższe wywołanie funkcji zwracają:
To jest piękny tekst |
Domyślne wartości argumentów
PHP wspiera obsługę domyślnych wartości argumentów, które nie muszą być wtedy podawane:
<? |
Oto różne wywołanie tej funkcji:
<? |
Powyższe wywołania funkcji test() zwracają:
Podano następujące argumenty: jeden |
Jak widać z powyższego przykładu, drugi argument ma przypisaną wartość domyślną, która jest używana w przypadku niepodania tego argumentu
Argumenty domyślne muszą być umieszczone na końcu aby było możliwe ich niepodawanie. Spójrzmy na przykład zadeklarowanie argumentów (zwróć uwagę na ich kolejność):
<? |
Oto różne wywołania tej funkcji:
<? |
Powyższe wywołania funkcji test() zwracają:
Podano następujące argumenty: |
Zwrócone ostrzeżenie świadczy o niepodaniu wymaganego argumentu wywołania funkcji.
Przy tego typu deklaracjach argumentów bardzo przydają się funkcje func_num_args(), func_get_arg() oraz func_get_args().
func_num_args()
Funkcja ta zwraca liczbę podanych argumentów wywołania funkcji:
<? |
Przykład wywołania funkcji:
<? |
Wynik działania funkcji:
Podano 5 argumentów! |
func_get_arg
Funkcja ta zwraca wartość podanego argumentu wywołania funkcji:
<? |
Przykład wywołania funkcji:
<? |
Wynik działania funkcji:
Trzeci argument: 3 |
func_get_args
Funkcja ta zwraca tablicę argumentów wywołania funkcji:
<? |
Przykład wywołania funkcji:
<? |
Wynik działania funkcji:
Podano następujące argumenty: |
PRZYKŁAD FUNKCJI
Napiszemy teraz funkcję, która będzie potrafiła podany tekst umieścić w znacznikach pogrubienia (<b> i </b>), podkreślenia (<u> i </u>), czy pochylenia (<i> i </i>), wykorzystując do tego celu wartości domyślne i instrukcję switch:
<?
function html($text, $type = "bold") {
switch($type) {
case "bold":
$zn = "b";
break;
case "underline":
$zn = "u";
break;
case "italic":
$zn = "i";
break;
}
$new_text = "<$zn>" . $text . "</$zn>" . "\n";
echo $new_text;
}
?>
Spójrzmy na przykład wywołania tej funkcji:
<?
html("To jest pogrubiony tekst...");
html("To jest pogrubiony tekst...", "bold");
html("To jest podkreślony tekst...", "underline");
html("To jest pochylony tekst...", "italic");
?>
Powyższe wywołania funkcji html() zwracają:
<b>To jest pogrubiony tekst...</b>
<b>To jest pogrubiony tekst...</b>
<u>To jest podkreślony tekst...</u>
<i>To jest pochylony tekst...</i>
KLASY
Klasy służą do przechowywania zmiennych i funkcji w jednym obiekcie o określonym identyfikatorze. Zostało już częściowo omówione w rozdziale zmienne.
TWORZENIE KLAS
Klasy tworzy się za pomocą słowa kluczowego class:
<? |
Jak widać z powyższego przykładu, klasy mogą przechowywać własne zmienne i funkcje (metody). W tym przypadku mamy dwie metody: dodawanie jabłek oraz wyświetlanie ich ilości.
TWORZENIE OBIEKTÓW
Aby możliwe było skorzystanie z klasy, należy stworzyć obiekt tej klasy za pomocą słowa kluczowego new:
<? |
|
Pełny przykład wykorzystania klasy koszyk został przedstawiony poniżej:
<? |
Ten kod zwróci ilość jabłek w koszyku, czyli:
Masz 8 jabłek w koszyku. |
Sesje
Czym są sesje?
Co mamy na myśli, mówiąc o sesjach? Nieformalnie, sesja w przypadku przeglądania WWW to czas, w którym dana osoba, siedząc przed jednym komputerem, przegląda określoną liczbę stron, następnie kończy ten proces. Jeżeli prowadzisz witrynę WWW, którą przykładowy użytkownik właśnie przegląda, sesja biegnie od czasu załadowania pierwszej strony, aż do ostatniej. Na przykład witryna hotelu na Karaibach może korzystać z sesji na czas przeglądania pięciu stron, ale użytkownik naprawdę rozpoczął sesję w portalu zajmującym się podróżami, a zakończył ją w czasie rezerwacji miejsca w hotelu konkurencji.
Co stanowi problem?
Dlaczego więc idea sesji jest na tyle skomplikowana? Jest tak dlatego, że protokól HTTP jest bezstanowy. Powoduje to, że twój serwer WWW na mniej pamięci długoterminowej niż twój kod. W rezultacie serwer WWW odpowiada na poszczególne żądania, jakie otrzymuje i nie ma sposobu na ich połączenie, nawet jeżeli żądania te są zapisywane. Jeżeli siądę przed swoim komputerem w Chicago a ty przy swoim, i oboje załadujemy kolejno pierwszą i drugą stronę z witryny hotelu na Karaibach, protokół HTTP nie zaoferuje żadnej pomocy przy rozpoznaniu, że tych dwoje ludzi oglądało dwie kolejne strony. Od strony serwera były to cztery żądania załadowania stron z dodatkowymi danymi związanymi z każdym wywołaniem. Nie tylko taka informacja nie identyfikuje cię (za pomocą nazwiska, adresu e-mail, numeru telefonu lub innego identyfikatora), ale również nie oferuje nic, co może zidetyfikować żądania kolejnych stron jako pochodzące od jednej osoby.
Dlaczego się tym zajmujemy?
Jeżeli twoja witryna jest przeznaczona tylko do dostarczania rozmaitych stron różnym użytkownikom, to w zasadzie nie musisz wiedzieć, kiedy sesja się rozpoczyna, a kiedy kończy. Jednak istnieje wiele sytuacji, kiedy chcemy to wiedzieć.
Chcemy dostosowywać się do doświadczenia użytkowników, które zależy od tego, jakie strony (lub ile) już widzieli.
Chcemy wyświetlać reklamy, ale nie chcemy wyświetlać jednej reklamy więcej niż raz w czasie sesji.
Chcemy zbierać informacje o podejmowanych przez użytkownika działaniach (tak jak w grach przygodowych realizuje się pamiętanie punktów lub w witrynach handlu elektronicznego - wózki na zakupy).
Interesuje nas sposób, w jaki ludzie korzystają z witryny - czy przechodzą do wewnętrznych stron korzystając z zakładek, czy przechodzą całą drogę od strony głównej.
Dla wszystkich zastosowań powinniśmy skorelować żądania załadowania stron z kolejnymi częściami sesji; dla niektórych zastosowań wygodnie byłoby zapamiętywać niektóre dane w połączeniu z sesją. Sesje PHP rozwiązują oba te problemy.
Alternatywy sesji:
Zanim zajmiemy się podejściem PHP do sesji, wymieńmy kilka alternatywnych sposobów rozwiązania problemu. Jak się później przekonamy, podejście PHP stanowi kombinację kilku z tych technik:
1. Adres IP
Serwery WWW znają albo nazwę, albo adres IP komputera, z którego przyszło żądanie załadowania strony. W większości konfiguracji PHP są one dostępne w zmiennych, odpowiednio $REMOTE_HOST i $REMOTE_NAME. Wydaje się, że identyfikacja komputera jest jednoznaczna z użytkownikiem, co najmniej w krótkim czasie. Jeżeli w krótkim okresie dostaniesz dwa żądania z tego samego adresu IP, kod może stwierdzić, że zostały one wysłane przez tę samą osobę, która przeszła z jednej strony witryny na drugą.
Niestety adres IP twojej przeglądarki nie musi pasować do komputera, z którego korzysta użytkownik. Zarówno AOL, jak i inni dostawcy internetu często stosują serwery proxy, które działają jako pośrednicy. Jeżeli przeglądarka zażąda załadowania URL, wysyła on to żądanie do docelowego serwera i zwraca stronę użytkownikowi. Taka konfiguracja powoduje, że wielu użytkowników może jednocześnie przeglądać twoją witrynę pozornie z jednego adresu IP. Adresy IP nie są więc wystarczająco jednoznaczne, aby stanowiś podstawę do śledzenia sesji.
2. Ukryte zmienne
Każde wywołanie HTTP jest obsługiwane niezależnie, ale za każdym razem gdy użytkownik przejdzie do innej strony witryny, jest zwykle realizowane przez łącze lub przetworzenie formularza. Jeżeli pierwsza strona, którą użytkownik odwiedza, może wygenerować identyfikator tej wizyty, a następne przejścia ze strony do strony mogą go przenosić.
Poniższy przykładowy fragment kodu można zamieścić na początku strony:
if(!isset($session_id)) |
Ten fragment kodu kontroluje, czy zmienna $session_id została wcześniej zainicjowana. Jeżeli tak, zakładamy, że została przekazana do bieżącej strony i jesteśmy w środku sesji. Jeżeli nie, oznacza to, że jesteśmy na pierszej stronie nowej sesji i wywołujemy hipotetyczną funkcję, nazwaną generate_session_id(), w celu utworzenia identyfikatora danej sesji.
Założyliśmy, że po włączeniu poprzedniego kodu identyfikator sesji został stworzony i teraz wystarczy przekazać go do innych połączonych stron. Każde łącze powinno zawierać $session_id jako argument GET:
<a href=next.php?session_id=$session_id>Następna strona</a> |
Każdy formularz powinien zawierać ukryty argument POST:
<form action=next.php method=post> |
Ta technika jest prostym sposobem odróżniania sesji (dopóki możesz generować identyfikatory). Jeśli mamy identyfikatory sesji, możemy zastosować wiele sposobów dołączania danych do każdej sesji. Jednym z nich jest użycie identyfikatora sesji jako klucza tabeli bazy danych. Jednak to wyjście jest kłopotliwe - musisz upewnić się, że każde łącze i obsługa formularza prawidłowo przenoszą opisane informacje. Jeżeli przesyłasz informacje jako argument GET, maszyna śledzenia sesji będzie widoczna w pasku adresu przeglądarki - argument może zostać łatwo zmieniony lub przechwycony przez użytkownika.
3. Cookie
Innym sposobem śledzenia sesji jest użycie takiego samego identyfikatora sesji, jak opisaliśmy przed chwilą, ale do jego przekazywania pomiędzy stronami stosuje się cookie.
Cookie jest szczególnego rodzaju plikiem, umieszczonym w komputerze z przeglądarką, który może być zapisywany i odczytywany przez serwery WWW. Zamiast sprawdzać zmienną przekazaną za pomocą metody POST lub GET (i przypisywać nową, jeżeli nie została odnaleziona), skrypt może sprawdzić, czy w komputerze klienta istnieje już poprzednio utworzone cookie i zapisać do niego nowy identyfikator, jeżeli nie został odnaleziony. Motoda ta posiada pewne zalety w porównaniu do ukrytych zmiennych: mechanizm ten działa w sposób niewidoczny (nie posiada zazwyczaj w przeglądarce śladów aktywności), a kod, który sprawdza i ustawia cookie może być scentralizowany (zamaiast występować w każdym łączu).
Jakie są wady? Niektóre stare przeglądarki w ogóle nie obsługują cookies, a nowe pozwalają użytkownikowi na zablokowanie możliwości osadzania cookies na dysku przez serwery WWW. Mimo, że cookie dostarczają dobre rozwiązanie problemu, nie możemy zakładać, że zawsze będą dostępne.
Jak działają sesje w PHP?
Dobrze działające sesje zajmują się dwiema rzeczami: śledzeniem sesji (to znaczy wykrywaniem, kiedy dwa osobne wywołania skryptów są częścią tej samej sesji, a kiedy nie) oraz zapamiętywaniem danych związanych z sesją. Musimy mieć pierwszą możliwość, żemy wogóle myśleć o drugiej.
Jeżeli PHP śledzi sesje, można również zachować dane przez "rejestrowanie" określonych zmiennych, w celu wskazania, że ich wartości mają być zapamiętane w połączeniu z identyfikatorem sesji.
Uaktywnianie sesji w PHP
Pierwszym krokiem skryptu, korzystającego z sesji, jest poinstruowanie PHP, że sesja może już trwać, więc trzeba ją przechwycić i odczytać wszystkie związane z nią dane. Realizuje się to przez wywołanie bezargumentowej funkcji session_start(). Jeżeli jest ona wywołana w każdym skrypcie, możesz ją pominąć i w zamian za to ustawić w php.ini zmienną session.auto_start na 1 (jest ona zwykle ustawiona na 0). Również każde wywołanie funkcji session_register() spowoduje niejawne wywołanie funkcji session_start().
Wynik działania session_start() zależy od tego, czy PHP odszukał poprzedni identyfikator sesji, przekazany przez argumenty HTTP lub cookie. Jeżeli został znaleziony, poprzednio związane z nim zmienne sesji zostaną odczytane i zamienione na zwykłe zmienne dostęne na stronie. Jeżeli na przykład poprzednia strona w sesji zarejestrowała zmienną $city i przypisała jej wartość 'Chicago', nasz skrypt może z niej skorzytstać, wywołując sesion_start():
session_start(); |
Jeżeli poprzednio nie została zarejestrowana taka zmienna lub zapomnieliśmy wywołać session_start(), zmienna będzie traktowana jak każda niezainicjowana zmienna.
Jeżeli PHP nie znajdzie poprzedniego identyfikatora sesji, wywołanie session_start() utworzy nową sesję. Podstawowym efektem jest utworzenie nowego identyfikatora, który może być używany do rejestrowania zmiennych.
Rejestrowanie zmiennych w sesji
Wywołanie session_start() zajmuje się importowaniem zmiennych z sesji do bieżącego skryptu - teraz wyeksportujemy zmienne, aby były widoczne w kolejnych stronach tej samej sesji. Jest to zrealizowane przez funkcję session_register(). Jak się okazuje, importowanie zmiennych jest "hurtowe" (robimy to jednym wywołaniem funkcji), natomiast eksport jest "detaliczny" (musimy rejestrować kolejno wszystkie zmienne). Należy pamiętać, że to, co zostało zaimportowane, nie jest automatycznie eksportowane, choć tak wskazuje logika.
Załóżmy, że poprzednia strona ustawiła zmienną $city na 'Chicago'. Teraz skorzystajmy z tej zmiennej i przekażmy ją (po zmianie wartości) do kolejnych stron:
session_start(); |
Wywołanie session_start() ustawia zmienną $city na 'Chicago', więc można użyć tej zmiennej w instrukcji echo czy print. Od tego miejsca $city będzie traktowana jak każda inna zmienna na stronie. Wywołanie session_register() umieszcza jednak w mechanizmie sesji informację o tym, że zmienna $city na być ponownie wyeksportowana do zmiennych sesji. Na kolejnych stronach wartość jej powinna być taka sama, jak po zakończeniu tego skryptu. W naszym kodzie wartość jej zmieniła się na 'Dallas', więc następne strony otrzymają taką właśnie wartość zmiennej.
Jeżeli zapomnimy wywołać funkcją session_start(), pierwszy wiersz będzie zawierał puste miejsca tam, gdzie powinna być wartość zmiennej $city. Drugi drukowany wiersz będzie już wyglądał dobrze, ponieważ wywołanie session_register() powoduje niejawne wywołanie session_start(). Jeżeli opuścimy wywołanie session_register(), na tej stronie wszystko będzie w porządku, ale kolejne strony nie otrzymają zmiennej sesji o nazwie $city.
Gdzie są przechowywane dane?
Mechanizm sesji bazuje na identyfikatorze sesji i związanych z nim zmiennych.
Jak już wiemy, identyfikator sesji jest przechowywany w cookie w komputerze z przeglądarką lub jest wbudowany w argumenty GET, POST, przekazywane razem z żądaniem pobrania strony. Nie jest nigdzie zapamiętywany - przekazywany jako część żądania i zwracany do kody HTML, do łączy i formularzy, które mogą wygenerować kolejne żądanie. Przeglądarka i serwer przerzucają się tą krytyczną dla nas informacją jak "gorącym kartoflem". Jeżeli któraś ze stron zgubi identyfikator, nasza sesja się kończy.
Domyślnie zawartość zmiennych sesji jest przechowywana w specjalnych plikach na serwerze, po jednym dla każdej sesji (można przechowywać identyfikator sesji jako cookie w komputerze klienta, ale byłoby grubiaństwem przechowywanie wartości zmiennych sesji na jego dysku). Zapamiętanie danych w ten sposób wymaga kodu sesji, realizującego serializację danych. Termin ten oznacza zamianę danych w liniową sekwencję bajtów, którą można zapisywać na dysku i odczytywać z niego w celu odtworzenia danych.
Możliwe jest takie skonfigurowanie PHP, aby program przechowywał zmienne sesji w bazie danych, zamiast w plikach
Funkcje obsługi sesji
Tabela poniżej zawiera wszystkie, najbardziej istotne funkcje związane z obsługą sesji:
Funkcja |
Opis |
session_start() |
Nie wymaga argumentu. Powoduje, że PHP odczytuje identyfikator sesji przekazany do strony (dzięki cookie lub GET, POST); jeżeli nie może go odszukać, tworzy nowy identyfikator sesji. |
session_register() |
Wymaga ciągu jako argumentu i rejestruje zmienną o nazwie określonej przez ciąg - na przykład session_register('username') rejestruje zmienną o nazwie username. Nazwa zmiennej nie powinna zawierać początkowego znaku '$'. Można równieżprzekazać tablicę ciągów, aby za jedym razem zarejestrować wiele zmiennych. |
session_unregister() |
Wymaga ciągu jako argumentu i usuwa z listy zarejestrowanych zmiennych zmienną o nazwie przekazanej jako argument. W wyniku tego zmienna ta nie będzie podlegała serializacji i nie będzie przenoszona pomiędzy stronami (nazwa zmiennej nie powinna zawierać początkowego znaku '$'. |
session_is_registered() |
Sprawdza, czy zmienna o podanej nazwie jest zarejestrowana w bieżącej sesji, zwracając TRUE, jeżeli zmienna jest zarejestrowana, FALSE, jeżeli nie jest. |
session_destroy() |
Wywołanie tej funkcji usuwa wszystkie zapamiętane dane o sesji (identyfikator sesji nie musi się zmieniać po wywołaniu tej funkcji). Wywołanie tej funkcji nie zmienia wartości żadnych zmiennych w bieżącym sktypcie. |
session_name() |
Funkcja wywołana bez parametrów zwraca nazwę bieżącej sesji. Jest to zwykle 'PHPSESSID'. |
session_module_name() |
Jeżeli nie zostaną podane żadne argumenty, funkcja zwraca nazwę modułu odpowiedzialnego za obsługę danych sesji. Nazwa ta jest domyślnie ustawiona na 'files', co oznacza, że dane sesji po serializacji są zapisywane do plików w katalogu ustawionym przez funkcję session_save_path(). Jeżeli podany zostanie ciąg jako argument, nazwa modułu jest zmienna na ten ciąg (np. 'user' dla zdefiniowanej przez użytkownika bazy danych sesji; ale nie powinieneś zmieniać tego parametru, jeżeli nie wiesz dokładnie co robisz). |
session_save_path() |
Zwraca (lub ustawia w przypadku podania argumentu) ścieżkę do katalogu, w którym zapisywane są wartości zmiennych sesji (zwykle jest to /tmp w systemach Unix). Katalog ten musi mieć odpowiednio ustawione uprawniwnia, aby PHP mógł tam zapisywać pliki. |
session_id() |
Nie ma argumentów. Zwraca ciąg, który jest kluczem, określającym sesje. Jeżeli zostanie przekazany argument, funkcja ta ustawi identyfikator sesji na tę wartość. |
session_encode() |
Zwraca ciąg z zakodowanym stanem bieżącej sesji, który może zostać zdekodowany przez funkcję session_decode(). Ciąg ten może zostać użyty do zapamiętania sesji w celu odtworzenia jej za jakiś czas (np. zapisanie zakodowanego ciągu w pliku lub w bazie danych). |
session_decode() |
Pobiera wynik działania funkcji session_encode() i odtwarza stan sesji, zmieniając zmienne sesji na zmienne strony (analogicznie do session_start()). |
Podsumowanie
Sesje są użyteczne w sytuacjach, gdy chcesz śledzić działania użytkownika w przypadku interakcji trwającej dłużej niż wykonanie jednego skryptu. Jeżeli prezentowana zawartość strony zależy od działań podejmowanych na poprzedniej, kod powinien zapamiętywać i przenosić te informacje w sposób, który umożliwia odróżnienie poszczególnych użytkowników. Ponieważ protokół HTTP jest protokołem bezstanowym, prowadzi to do zastosowania technik zastępczych - zwykle albo ukrytych zmiennych (które są niestety kłopotliwe), albo cookies (niektóre przeglądarki klientów ich nie obsługują).
Implementacja sesji w PHP hermetyzuje te skomplikowane zagadnienia. Identyfikatory sesji są tworzone i rozprowadzone w sposób automatyczny, a mechanizm rejestracji pozwala programiście dołączać dowolne dane PHP do sesji. Poza początkowym dołączeniem się do sesji i zarejestrowaniem zmiennych, które powinny zostać rozpropagowane poza bieżącą stronę, użycie sesji jest dla programisty przejrzyste.
Grafika w PHP
Programowanie w PHP nie kończy sie na operacjach na plikach i korzystania z bazy danych. Można dzięki niemu tworzyć grafikę i zapisywać ją do plików lub wyświetlać na stronie. Ten artykuł ma ci pomóc w tworzeniu obrazków w PHP.
Co będzie potrzebne?
Aby tworzyć grafikę za pomocą PHP musisz mieć zainstalowaną bibliotekę GD zintegrowaną z twoim interpreterem PHP. Aktualnie biblioteka GD jest dodawana do każdej wersji PHP. W wersji 4.0.6 biblioteka ta znajduje się w katalogu extensions i nazywa się php_gd.dll. Aby uruchomić tę bibliotekę w interpreterze PHP należy w pliku php.ini zmienić linijkę extension_dir = ./ na extension_dir = ./extensions oraz ;extension=php_gd.dll na extension=php_gd.dll. Teraz zapisz plik i jeżeli chodzi o instalację to wszystko!
Programowanie
Najnowsza biblioteka GD obsługuje tylko formaty PNG i JPEG. Funkcje obsługujące te formaty nazywają się tak samo z wyjątkiem dwóch: imagePNG()/imageJPEG() i imagecreatefromPNG()/imagecreatefromJPEG(). Jednak przed użyciem w skrypcie jakichkolwiek funkcji graficznych należy poinformować interpreter i przeglądarkę, że przesyłane dane to grafika. Robimy to za pomocą funkcji Header(), np.:
Header("Content-type: image/png");
Header("Content-type: image/jpeg");
Pierwsza funkcja instruuje interpreter, że przesyłane dane to plik graficzny w formacie PNG, a druga, że w formacie JPEG.
Gdy już poinformowaliśmy przeglądarkę, że skrypt tworzy grafikę, powinniśmy utworzyć nowy rysunek. Służy do tego funkcja imagecreate(), posiadająca dwa parametry - szerokość i wysokość obrazka. Przykład użycia tej funkcji:
$rysunek = imagecreate(200, 200);
W ten oto sposób stworzyliśmy obrazek w kształcie kwadratu o wymiaracha 200x200. Zmienna $rysunek to uchwyt do tego właśnie rysunku. Uchwyt ten będzie potrzebny przy wszystkich operacjach na rysunku.
Kolejną podstawową funkcją w programowaniu grafiki w PHP jest imagePNG() bądź też imageJPEG(), zależnie od formatu. Parametrami tej funkcji są:
- uchwyt obrazka
- nazwa pliku do którego ma być zapisany rysunek - jest to parametr opcjonalny, jeżeli nie wpiszesz jego wartości, interpreter prześle rysunek wprost do przeglądarki, mówiąc prościej - wyświetli go w przeglądarce.
Przykładowe użycia tej funkcji:
imagePNG($rysunek);
imagePNG($rysunek,"rysuj.png");
imageJPEG($rysunek);
imageJPEG($rysunek,"rysuj.jpg");
W pierwszym przykładzie wyświetlamy rysunek w formacie PNG. W drugim tworzymy plik z rysunkiem o nazwie rysuj.png w formacie PNG. Następny wyświetla rysunek w formacie JPEG. No i ostatni zapisuje rysunek do pliku o nazwie rysuj.jpg w formacie JPEG.
Ostatnią ważną funkcją, którą powinniśmy stosować na końcu każdego skryptu tworzącego grafikę jest imagedestroy(). Jedynym parametrem tej funkcji jest uchwyt obrazka. Funkcja ta usuwa z obrazek z pamięci komputera.
Poznaliśmy już wszystkie funkcje inicjujące, teraz powinniśmy zająć się... rysowaniem. Przy rysowaniu należy pamiętać, że obrazek zaczyna się na współrzędnych 0 0, a kończy się na maksymalnej szerokości minus 1 i maksymalnej wysokości minus 1. Tak więc przy obrazku wielkości 10x10, ostatnim widocznym pikselem będzie 9 9.
Spis wszystkich funkcji zajmujących się obróbką obrazu zamieszczam w poniższej tabelce:
imagearc(int $uchwyt, $sx, $sy, $szer, $wys, $pocz_kata, $kon_kata, $kolor) |
Tworzy wycinek elipsy o środku $sx $sy o szerokości $szer i wysokości $wys, między kątem $pocz_kata a $kon_kata w kolorze równym $kolor. |
imagechar(int $uchwyt, $czcionka, $x, $y, string $znak, int $kolor) |
Rysuje znak poziomo od punktu $x $y, w danym kolorze. Standardowo w PHP istnieją czcionki od 1-5. |
imagecharup(int $uchwyt, $czcionka, $x, $y, string $znak, int $kolor) |
Rysuje znak pionowo od punktu $x $y, w danym kolorze. |
int imagecolorallocate(int $uchwyt, $red, $green, $blue) |
Zwraca uchwyt barwy o podanej zawartości kolorów RGB. |
imagecopyresized(int $uchwyt_docelowy, $uchwyt_zrodlowy, $docel_x, $docel_y, $zrodl_x, $zrodl_y, $docel_szer, $docel_wys, $zrodl_szer, $zrodl_wys) |
Kopiuje wycinek z obrazka źródłowego o punkcie początkowym $zrodl_x $zrodl_y, szerokości $zrodl_szer i wysokości $zrodl_wys. Następnie wkleja do obrazka docelowego zaczynając od punktu $docel_x $docel_y, zmieniając szerokość wycinka do $docel_szer i wysokość do $docel_wys. |
int imagecreatefromJPEG(string $url_obrazka) |
Tworzy uchwyt do obrazka w formacie JPEG z pliku o podanym urlu. |
int imagecreatefromPNG(string $url_obrazka) |
Tworzy uchwyt do obrazka w formacie PNG z pliku o podanym urlu. |
imagedashedline(int $uchwyt, $x1, $y1, $x2, $y2, $kolor) |
Rysuje przerywaną linię z punktu $x1 $y1 do punktu $x2 $y2 w podanym kolorze. |
imagefill(int $uchwyt, $x, $y, $kolor) |
Zalewa obrazek kolorem z punktu $x $y do pierwszej napotkanej linii tego samego koloru. |
imagefilledpolygon(int $uchwyt, array $tablica_punktow, int $ilosc_punktow, $kolor) |
Rysuje wypełniony kolorem wielokąt. Współrzędne wszystkich punktów są zawarte w tablicy punktów, w której indeksy parzyste to współrzędne x wierzchołków wielokąta, a nieparzyste to współrzędne y wierzchołków wielokąta. |
imagefilledrectangle(int $uchwyt, $x1, $y1, $x2, $y2, $kolor) |
Rysuje wypełniony kolorem prostokąt, którego lewy-górny wierchołek ma współrzędne $x1 $y1, a prawy-dolny $x2 $y2. |
imagefilltoborder(int $uchwyt, $x, $y, $kol_graniczny, $kolor) |
Wypełnia rysunek kolorem od punktu $x $y do linii o podanym kolorze - $kol_graniczny. |
int imagefontheight(int $czcionka) |
Zwraca wysokość czcionki w pikselach. |
int imagefontwidth(int $czcionka) |
Zwraca szerokość czcionki w pikselach. |
imageinterlace(int $uchwyt, $przeplot) |
Włącza ($przeplot=1) lub wyłącza ($przeplot=0) przeplot. |
imageline(int $uchwyt, $x1, $y1, $x2, $y2, $kolor) |
Rysuje prostą z punktu $x1 $y1 do punktu $x2 $y2 w podanym kolorze. |
int imageloadfont(string $plik) |
Ładuje nową czcionkę. Plik z definicją czcionki powinien być wygenerowany na komputerze z takim samym procesorem, w jaki został wyposażony komputer z interpreterem PHP. |
imagepolygon(int $uchwyt, array $punkty, int $il_punktow, $kolor) |
Rysuje wielokąt, którego współrzędne wierzchołków są zapisane w formie tablicy, gdzie indeksy parzyste to współrzędne x, a indeksy nieparzyste to współrzędne y, a ilość wierzchołków jest zapisana jako $il_punktow. |
imagerectangle(int $uchwyt, $x1, $y1, $x2, $y2, $kolor) |
Rysuje prostokąt, którego lewy-górny wierzchołek ma współrzędne $x1 $y1, a prawy-dolny $x2 $y2. Zmienna $kolor przechowuje kolor krawędzi tego prostokąta. |
imagesetpixel(int $uchwyt, $x, $y, $kolor) |
Rysuje pojedynczy piksel o współrzędnych $x $y w podanym kolorze. |
imagestring(int $uchwyt, $czcionka, $x, $y, string $lancuch, int $kolor) |
Rysuje łańcuch znaków w podanej czcionce i kolorze, zaczynając od punktu $x $y. |
imagestringup(int $uchwyt, $czcionka, $x, $y, string $lancuch, int $kolor) |
Rysuje w pionie łańcuch znaków w podanej czcionce i o podanym kolorze, zaczynając od punktu $x $y. |
int imagesx(int $uchwyt) |
Zwraca szerokość obrazka |
int imagesy(int $uchwyt) |
Zwraca wysokość obrazka |
imagettftext(int $uchwyt, $wielkosc, $kat, $x, $y, $kolor, string $plik, $tekst) |
Wyświetla tekst przy użyciu czcionki True Type, znajdującej się w pliku zaczynając od punktu $x $y w podanym kolorze. Jeżeli $kat jest równy 0, to napis jest rysowany w poziomie. Funkcja potrzebuje dodatkowo biblioteki Freetype. |
int imagecolorat(int $uchwyt, $x, $y) |
Zwraca indeks koloru piksela o współrzędnych $x $y. |
int imagecolorclosest(int $uchwyt, $red, $green, $blue) |
Zwraca indeks najbliższego koloru. |
int imagecolorexact(int $uchwyt, $red, $green, $blue) |
Zwraca indeks koloru. |
int imagecolorresolve(int $uchwyt, $red, $green, $blue) |
Zwraca indeks koloru, jeżeli nie ma takowego w palecie obrazka zwraca najbliższy mu. |
bool imagecolorset(int $uchwyt, $indeks, $red, $green, $blue) |
Określa kolor podanego indeksu palety |
array imagecolorsforindex(int $uchwyt, $indeks) |
Zwraca tablicę asocjacyjną kolorów RGB palety o podanym indeksie. Indeksami poszczególnych kolorów są: "red", "green" i "blue". |
int imagecolorstotal(int $uchwyt) |
Zwraca ilość kolorów zawartych w palecie obrazka |
Oto przykładowy skrypt wykorzystujący bibliotekę GD. Ma on generować szachownicę o ilości pól x*x. Dla skrócenia kodu x ustaliłem sam i ma on wartość 100. Można oczywiście stworzyć formularz, który będzie wysyłał zmienną x do tego skryptu.
<?PHP
Header("Content-type: image/png");
$img = imagecreate(200, 200);
$bialy = imagecolorallocate($img, 255, 255, 255);
$czarny = imagecolorallocate($img, 0, 0, 0);
imagefill($img, 0, 0, $bialy);
$x = 100;
$y = round(200/$x);
for($i=0;$i<$x;$i++)
for($j=0;$j<$x;$j++) {
if(($i+$j)%2==0) {
imagefilledrectangle($img,$j*$y,$i*$y,$j*$y+$y,$i*$y+$y,$bialy);
} else
imagefilledrectangle($img,$j*$y,$i*$y,$j*$y+$y,$i*$y+$y,$czarny);
}
imagePNG($img);
imagedestroy($img);
?>
MySQL
CZYM JEST BAZA DANYCH?
Coraz częściej zachodzi potrzeba pobierania i przechowywania danych od użytkownika. Do przechowywania danych najlepiej użyć właśnie baz danych. Czym one są, dowiesz się czytając tą część kursu.
POJĘCIE BAZY DANYCH
Z bazami danych spotkałeś się już pewnie niejeden raz. Bazą danych jest na przykład książka adresowa w Twoim programie pocztowym. Bazy danych używane są w bankach i większych przedsiębiorstwach do przechowywania informacji o kontach czy też danych personalnych.
Przechowywanie danych w bazach odbywa się w określony sposób. Na bazę danych składają się tabele, a w nich rekordy podzielone na pola.
RODZAJE BAZ DANYCH
Bazy danych możemy podzielić na płaskie i relacyjne.
Płaskie bazy danych
Tego typu bazy danych to nic innego jak pliki tekstowe, w których zastosowano odpowiedni klucz podziału na rekordy i pola. Najczęściej rekordy są osobnymi liniami pliku, a pola oddzielone są umownym znakiem, np. średnikiem, dwukropkiem, czy tabulatorem. Trzeba jednak pamiętać o tym, że znak separacji nie może występować w zawartości pól. Można również zdefiniować długość poszczególnych pól; nie ma wtedy potrzeby oddzielania ich, ponieważ wiadomo w którym miejscu zaczyna się odpowiednie pole.
Poniższy przykład prezentuje płaską bazę danych:
1;Noc na ziemi;Jim Jarmush |
W powyższym przykładzie można wyróżnić trzy pola: numer pozycji (id), tytuł oraz reżysera filmu. Pola oddzielone zostały za pomocą średnika. Taki plik tekstowy nie jest jednak łatwy w edycji i jest mało wydajnym rozwiązaniem. Nadaje się za to do prostych czynności, na przykład przechowywania wartości, które nie są poddawane częstej edycji, oraz tam, gdzie nie ma dostępu do serwera baz danych, a wydajność przyjętego rozwiązania nie jest najważniejsza.
Relacyjne bazy danych
Relacyjne bazy danych są dużo wydajniejsze niż pliki tekstowe, a ich obsługa za pomocą języka zapytań SQL jest prosta i przyjemna. Relacyjne bazy danych składają się z kolumn i rekordów. Każda kolumna ma swoją nazwę, a każdy rekord przechowuje inną pozycję. Pola są określonego typu, dlatego można w nich łatwo przechowywać teksty, liczby, daty czy obrazki. Klucze podstawowe umożliwiają jednoznaczną identyfikację danego rekordu. W poprzednim przykładzie takim kluczem byłoby pole zawierające numer pozycji (id). W relacyjnych bazach danych kolejność rekordów nie ma znaczenia, ponieważ za pomocą języka SQL można nie tylko wybrać interesujące nas rekordy, ale również je posortować.
BAZY DANYCH OBSLUGIWANE PRZEZ PHP
PHP ma wbudowane funkcje obsługi następujących baz danych:
Adabas D
dBase
Empress
FilePro (tylko do odczytu)
Hyperwave
IBM DB2
Informix
Ingres
InterBase
FrontBase
mSQL
Direct MS-SQL
MySQL
ODBC
Oracle (OCI7 i OCI8)
Ovrimos
PostgreSQL
Solid
Sybase
Velocis
Unix dbm
CZYM JEST MySQL?
MySQL jest szybkim, wielowątkowym serwerem baz danych obsługującym język zapytań SQL. Pracuje z wieloma użytkownikami i doskonale nadaje się do wykorzystania razem z PHP jako darmowa platforma aplikacji internetowych.
W MySQL-u możesz między innymi tworzyć nowe bazy danych, a w nich tabele, dodawać nowe rekordy, edytować je lub usuwać. Masz do dyspozycji możliwość zarządzania użytkownikami, w tym również dokładnego określania praw dostępu do określonego pola w bazie danych.
W danym momencie z bazy danych może korzystać nieograniczona liczba osób; zależy to jedynie od zasobów fizycznych serwera.
Wszystkie przykłady obsługi MySQL-a w tym kursie będą opierać się na lokalnej bazie danych, zainstalowanej pod systemem Windows.
LOGOWANIE
Pierwszą rzeczą, jaką chciałbyś zrobić jest pewnie "zobaczenie" MySQL-a. Musisz się do niego najpierw zalogować. W okienku DOS-a przejdź do katalogu z binariami MySQL-a. Domyślnie jest to katalog c:\apache\mysql\bin:
c:\windows>cd .. |
Następnie wpisz mysql z parametrami -u (użytkownik) oraz jeśli wymagane jest hasło to również -p:
c:\apache\mysql\bin>mysql -u root -p |
MySQL wypisuje zarówno informacje na temat serwera bazy danych, jak i numer identyfikacyjny połączenia z bazą danych. Mamy również do dyspozycji znak zachęty MySQL-a (mysql>).
Jeśli instalowałeś pakiet PHP Triad, to MySQL nie ma jeszcze ustawionego hasła dla użytkownika root i nie ma potrzeby jego podawania.
Składnia wywołania mysql przedstawia się następująco:
mysql [-h adres_hosta] [-u nazwa_użytkownika] [-p twoje_haslo] |
Adres hosta to adres komputera, na którym znajduje się serwer bazy danych. Domyślnie jest to adres komputera lokalnego (localhost). MySQL domyślnie loguje właśnie do tego hosta.
WYŚWIETLANIE ISTNIEJĄCYCH BAZ DANYCH
Z pewnością chciałbyś wiedzieć, jakie bazy danych są dostępne, zanim zazcniesz tworzyć nowe, własne bazy. Aby wyświetlić listę dostępnych baz danych posłużmy się poleceniem show databases. Zaloguj się do MySQL-a i wydaj polecenie show databases;:
mysql> show databases; +----------+ | Database | +----------+ | mysql | | test | +----------+
2 rows in set (0.00 sec) |
Jak już pewnie zauważyłeś, polecenie show databases zostało zakończone znakiem średnika (podobnie jak w PHP). SQL wymaga kończenia zapytań średnikiem, co pozwala na zapisywanie jednej instrukcji w wielu liniach. Spójrzmy na przykład:
mysql> show databases +----------+ | Database | +----------+ | mysql | | test | +----------+
2 rows in set (0.00 sec) |
Zwróć uwagę, że nie został podany średnik po poleceniu i MySQL czeka na kolejne dane. Dopiero kiedy zakończysz linię średnikiem, polecenie zostanie wykonane.
Jak widać, w systemie mamy utworzone dwie bazy danych, mysql i test. Pierwsza to baza o specjalnym znaczeniu; to w niej MySQL przechowuje wszystkie dane na temat użytkowników i ich uprawnień. Druga to specjajnie utworzona, pusta baza danych do testów.
TWORZENIE NOWEJ BAZY DANYCH
Aby rozpocząć naukę MySQL-a, utwórzmy najpierw naszą pierwszą, przeznaczoną do testów bazę danych. Tworzenie zarówno tabel, jak i baz odbywa się za pomocą polecenia create z odpowiednimi argumentami (w tym przypadku database i nazwą bazy, którą chcemy utworzyć):
mysql> create database nasza_baza; |
Właśnie utworzyliśmy nową bazę danych o nazwie nasza_baza. MySQL poinformował nas o powodzeniu i czasie wykonania polecenia. Spójrzmy zatem na listę dostępnych baz danych:
mysql> show databases; +------------+ | Database | +------------+ | mysql | | test | | nasza_baza | +------------+
3 rows in set (0.00 sec) |
Jak widać pojawiła się tam nowa pozycja, nasza_baza.
USUWANIE BAZY DANYCH
Ponieważ utworzyliśmy własną bazę danych do testów, nie jest już nam potrzebna baza test. Usuńmy ją za pomocą polecenia drop z odpowiednimi argumentami (w tym przypadku databases i nazwą bazy, którą chcemy usunąć):
mysql>drop database test; |
Sprawdźmy, jakie bazy są teraz dostępne:
mysql> show databases; +------------+ | Database | +------------+ | mysql | | nasza_baza | +------------+
2 rows in set (0.00 sec) |
Jak widać pozycja test nie jest wyświeltana, ponieważ została usunięta wraz z danymi, które mogły się tam znajdować.
PRACA Z TABELAMI
Ta część kursu przybliży Ci temat tworzenia tabel i zarządzania nimi.
Tabelę można zdefiniować jaki plik, w którym w rekordach i polach przechowywane są dane.
WYBIERANIE BAZY DANYCH
Aby możliwe było zarządzanie tabelami (tworzenie, edycja bądź edytowanie) musimy najpierw "powiedzieć" MySQL-owi, nad którą bazą danych mamy zamiar pracować. Można to zrobić na dwa sposoby:
podając ścieżkę do tabeli w notacji <nazwa_bazy>.<nazwa_tabeli>
lub wywołując komendę use <nazwa_bazy>. Wtedy nie musimy już podawać przed nazwą tabeli nazwy bazy, ponieważ domyślnie to w niej MySQL szuka podanej tabeli.
Spójrzmy na przykład z zastosowaniem komenty use:
mysql> use nasza_baza |
WYŚWIETLANIE ISTNIEJĄCYCH TABEL
Kiedy baza została już wybrana (w tym przypadku nasza_baza), możemy przystąpić do wyświetlania tabel. Do tego celu służy poznana wcześniej komenda show z argumentem tables:
mysql> show tables |
Zwrócony komunikat świadczy o tym, że baza nasza_baza jest pusta. Teraz spróbujemy wyświetlić tabelę w bazie mysql; wcześniej jednak skorzystamy z komendy use, aby zmienić bazę, nad którą chcemy pracować:
mysql> use mysql +-----------------+ | Tables_in_mysql | +-----------------+ | columns_priv | | db | | host | | tables_priv | | user | +-----------------+
5 rows in set (0.00 sec) |
Jak widać, w bazie mysql znajduje się pięć tabel: columns_priv, db, host, tables_priv oraz user.
TWORZENIE TABELI
Skoro mamy już wcześniej stworzoną bazę danych nasza_baza, warto byłoby utworzyć w niej nową tabelę. Do tego celu służy poznana już wcześniej komenda create z argumentem table <nazwa_tabeli> oraz definicją listy pól. Wybrane typy pól są przedstawione poniżej.
Typ pola |
Opis |
CHAR(M) |
Pole znakowe. Przechowuje teksty o ustalonej z góry długości. Ograniczone do 255 znaków. |
VARCHAR(M) |
Pole znakowe. Przechowuje taką długość tekstu, jaka jest używana. |
INT[(M)] [UNSIGNED] |
Pole liczb całkowitych. Przechowuje liczby z zakresu od -2147483648 do 2147483647 (z parametrem UNSIGNED - od 0 do 4294967295). |
DATE |
Pole daty przechowuje daty z zakresu od '1000-01-01' do '9999-12-31'. |
BLOB/TEXT |
Pole tekstowe. Przechowuje dłuższe, wielowierszowe teskty do 65535 znaków. |
Spróbujmy teraz utworzyć tabelę do przechowywania adresów przyjaciół:
mysql> use nasza_baza |
Właśnie utworzyliśmy tabelę adresy w bazie nasza_baza. Nowa tabela zawiera cztery pola. Pole id pełni funkcję klucza podstawowego (PRIMARY KEY), który jednoznacznie identyfikuje dany rekord. Jest ono typu auto_increment, co oznacza, że MySQL automatycznie będzie wstawiał do niego wartość o jeden większą, a po usunięciu któregoś z rekordów wartości nie przesuną się "w górę"; zawsze będą takiem same. Poza tym pole id nie może być puste (NOT NULL). Pola imie oraz nazwisko mają domyślnie wstawianą wartość, jeżeli nie została podana (DEFAULT).
Jeżeli chcesz obejrzeć strukturę tabeli użyj polecenia describe <nazwa tabeli>:
mysql> describe adresy; +----------+-------------+------+-----+----------------+------------+ | Field | Type | Null | Key | Extra | Privileges | +----------+-------------+------+-----+----------------+------------+ | id | int(11) | | PRI | auto_increment | zobacz * | | imie | varchar(15) | YES | | | zobacz * | | nazwisko | varchar(25) | YES | | | zobacz * | | adres | blob | YES | | | zobacz * | +----------+-------------+------+-----+----------------+------------+
4 rows in set (0.00 sec)
* = select,insert,update,references |
MySQL wylistował nam wszystkie cztery pola, wyświeltił ich typy, klucze i wartości domyślne. Za pomocą tego polecenia możesz szybko zorientować się w strukturze każdej tabeli.
Możesz użyć również synonimicznej funkcji show columns from <nazwa_tabeli> dla wylistowania pól tabeli.
Sprawdźmy zatem co zwróci teraz polecenie show tables:
mysql> show tables; +----------------------+ | Tables_in_nasza_baza | +----------------------+ | adresy | +----------------------+
1 row in set (0.05 sec) |
EDYCJA TABELI
Po utworzeniu tabeli zawsze możesz jej strukturę poddać edycji. W naszej tabeli przydałoby się jeszcze jedno pole przechowujące adres e-mail przyjaciela. Do edycji tabel służy polecenie alter z argumentem table <nazwa_tabeli>:
mysql> ALTER TABLE adresy ADD adres_email VARCHAR(100); |
Nowe pole o nazwie adres_email zostało już dodane, spójrzmy zatem na wynik naszej pracy:
mysql> describe adresy; +-------------+--------------+------+-----+----------------+------------+ | Field | Type | Null | Key | Extra | Privileges | +-------------+--------------+------+-----+----------------+------------+ | id | int(11) | | PRI | auto_increment | zobacz * | | imie | varchar(15) | YES | | | zobacz * | | nazwisko | varchar(25) | YES | | | zobacz * | | adres | blob | YES | | | zobacz * | | adres_email | varchar(100) | YES | | | zobacz * | +-------------+--------------+------+-----+----------------+------------+
5 rows in set (0.00 sec)
* = select,insert,update,references |
Jak widać, nowe pole występuje już na liście, ale jego nazwa nie jest zbyt udana. Zmieńmy ją na email:
mysql> ALTER TABLE adresy CHANGE adres_email email VARCHAR(100); |
Przy zmianie nazwy pola należy podać jego nową definicję (czyli typ pola). Spróbujmy zmienić maksymalną długość pola email ze 100 znaków na 80:
mysql> ALTER TABLE adresy MODIFY email VARCHAR(80); |
Jak widać z powyższego przykładu, przy zmianie jedynie właściwości pola posługujemy się komendą MODIFY, a nie CHANGE, jak w poprzednim przykładzie, gdzie zmienialiśmy nazwę pola (kolumny).
Sprawdźmy jeszcze, jak wygląda struktura naszej tabeli po tych zmianach:
mysql> describe adresy; +----------+-------------+------+-----+----------------+------------+ | Field | Type | Null | Key | Extra | Privileges | +----------+-------------+------+-----+----------------+------------+ | id | int(11) | | PRI | auto_increment | zobacz * | | imie | varchar(15) | YES | | | zobacz * | | nazwisko | varchar(25) | YES | | | zobacz * | | adres | blob | YES | | | zobacz * | | email | varchar(80) | YES | | | zobacz * | +----------+-------------+------+-----+----------------+------------+
5 rows in set (0.00 sec)
* = select,insert,update,references |
Sróbujmy jeszcze dokonać dwu modyfikacji w strukturze naszej tabeli. Najpierw usuńmy pole nazwisko:
mysql> ALTER TABLE adresy DROP COLUMN nazwisko; |
A następnie dodajmy pole telefon, które ma występować bezpośrednio po polu adres:
mysql> ALTER TABLE adresy ADD telefon VARCHAR(15) AFTER adres; |
Aby dodać nowe pole po innym, używa się komendy AFTER. Aby natomiast dodać pole na początku tabeli, trzeba użyć komendy FIRST.
Spójrzmy jak teraz wygląda struktora naszej tabeli:
mysql> describe adresy; +----------+-------------+------+-----+----------------+------------+ | Field | Type | Null | Key | Extra | Privileges | +----------+-------------+------+-----+----------------+------------+ | id | int(11) | | PRI | auto_increment | zobacz * | | imie | varchar(15) | YES | | | zobacz * | | adres | blob | YES | | | zobacz * | | telefon | varchar(15) | YES | | | zobacz * | | email | varchar(80) | YES | | | zobacz * | +----------+-------------+------+-----+----------------+------------+
5 rows in set (0.00 sec)
* = select,insert,update,references |
I na koniec zmieńmy nazwę naszej tabeli z adresy na ksiazka_adresowa:
mysql> ALTER TABLE adresy RENAME ksiazka_adresowa; |
Wyświetlmy teraz listę tabel w bazie nasza_baza:
mysql> show tables; +----------------------+ | tables_in_nasza_baza | +----------------------+ | ksiazka_adresowa | +----------------------+
1 row in set (0.00 sec) |
Jak widać zmiana nazwy tabeli się powiodła.
USUWANIE TABELI
Przećwiczmy teraz usuwanie tabel, ale nie na tabeli ksiazka_adresowa, ponieważ przyda się nam ona później. Utwórzmy nową tabelę do_usuniecia z jednym polem o nazwie test:
mysql> CREATE TABLE do_usuniecia ( |
Wyświetlmy listę tabel dla bazy nasza_baza:
mysql> show tables; +----------------------+ | tables_in_nasza_baza | +----------------------+ | do_usuniecia | | ksiazka_adresowa | +----------------------+
2 rows in set (0.00 sec) |
Usuńmy teraz tabele do_usuniecia za pomocą poznanej już komendy DROP z parametrem table <nazwa_tabeli>:
mysql> DROP TABLE do_usuniecia; |
Sprawdźmy listę table w naszej bazie:
mysql> show tables; +----------------------+ | tables_in_nasza_baza | +----------------------+ | ksiazka_adresowa | +----------------------+
1 row in set (0.00 sec) |
Jak widać wszysko się powiodło i nie ma już tabeli do_usuniecia. W naszej bazie znajduje się jedynie tabela ksiazka_adresowa.
JĘZYK SQL
Ta część kursu przybliży Cię temat dodawania, wybierania, edycji i usuwania rekordów za pomocą języka SQL. Poznasz polecenia INSERT, SELECT, UPDATE i DELETE. W nazwach poleceń SQL wielkość liter nie ma znaczenia; możesz pisać polecenia małymi literami (co trochę przyspiesza pracę), w przykładach zostały jednak zastosowane wielkie litery dla zachowania czytelności kodu.
DODAWANIE REKORDÓW
Do dodawanie rekordów używa się polecenia INSERT. Spójrzmy na najprostszy przykład dodawania nowego rekordu do naszej książki adresowej w testowanej bazie danych:
mysql> INSERT INTO nasza_baza.ksiazka_adresowa VALUES(0,'Jan','ul. Wrocławska 5','888-55-41','jan@email.pl'); |
Jak już pewnie zauważyłeś, polecenie dodawania nowego rekordu składa się z następujących części:
INSERT INTO <nazwa_bazy>.<nazwa_tabeli> lub tylko <nazwa_tabeli>, jeżeli zostało wcześniej wywołane zostało polecenie use <nazwa_bazy>,
VALUES().
W nawiasach okrągłych po słowie kluczowym VALUES wypisujemy listę wartości dla pól rekordu, który zamierzamy podać. Jakie i jakiego typu są te pola sprawdzimy znanym już poleceniem:
mysql> describe ksiazka_adresowa; +----------+-------------+------+-----+--------------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+-------------+------+-----+--------------+----------------| | id | int(11) | | PRI | NULL | auto_increment | | imie | varchar(15) | YES | | <podaj_imie> | | | adres | blob | YES | | NULL | | | telefon | varchar(15) | YES | | NULL | | | email | varchar(80) | YES | | NULL | | +----------+-------------+------+-----+--------------+----------------+
5 rows in set (0.00 sec) tabela została skrócona dla zwiększenia czytelności kodu |
Ze struktury tabeli wynika, że jeżeli nie podamy imienia, zostanie zapisana wartość domyślna '<podaj_imie>'. Ale co zrobić, żeby nie podać wartości dla danego pola? Możemy oczywiści postąpić tak (wtedy jednak wartość domyślna nie zostanie wstawiona):
mysql> INSERT INTO ksiazka_adresowa VALUES(0,'','ul Krakowska 16','777-33-84','zebra@zoo.pl'); |
Jest jednak lepszy sposób - wpisanie listy pól, dla których zamierzamy podać wartości, w nawaisach okrągłych występujących po nazwie tabeli:
mysql> INSERT INTO ksiazka_adresowa(id, adres, telefon) VALUES(0,'ul. Warszawska 15','458-34-75'); |
Zauważyłeś pewnie, że zamiast wpisywać kolejne numery id, podajemy za każdym razem zero, a przecież taki sam numer id we wszystkich rekordach nic nam nie da. Zauważ jednak, że pole id jest typu auto_increment i nie ma znaczenia co do niego wpisujemy, i tak będzie miało odpowiednio inkrementowaną wartość. Dlatego lepiej byłoby, dodawać rekordy bez podawania pola id:
mysql> INSERT INTO ksiazka_adresowa(telefon, email) VALUES('471-84-36','my@email.pl'); |
Spójrzmy co zwróci MySQL, gdy nie podamy wszystkich wartości, dla których zgłosiliśmy pola:
mysql> INSERT INTO ksiazka_adresowa(telefon, adres) VALUES('433-22-88'); |
Zwrócony komunikat świadczy o niezgodności listy pól z wartościami. rekord nie został dodany do naszej tabeli.
WYBIERANIE REKORDÓW
Chciałbyś pewnie wiedzieć, jak wygląda po tych operacjach nasza tabela ksiazka_adresowa. Jest na to sposób: polecenie SELECT, które służy do wybierania w rozmaity sposób rekordów z bazy danych. Podstawowa składnia tego polecenia wygląda następująco:
SELECT <lista_pól> FROM <nazwa_bazy>.<nazwa_tabeli>; |
lub
SELECT <lista_pól> FROM <nazwa_tabeli>; |
jeżeli wcześniej zostało użyte polecenie use <nazwa_bazy>. Spójrzmy zatem, co zwróci polecenie SELECT użyte w stosunku do naszej tabeli:
mysql> SELECT * FROM ksiazka_adresowa; +----+--------------+--------------------+-----------+--------------+ | id | imie | adres | telefon | email | +----+--------------+--------------------+-----------+--------------+ | 1 | Jan | ul. Wrocławska 5 | 888-55-41 | jan@email.pl | | 2 | | ul Krakowska 16 | 777-33-84 | zebra@zoo.pl | | 3 | <podaj imie> | ul. Warszawska 15 | 468-34-75 | NULL | | 4 | <podaj imie> | NULL | 471-84-36 | my@email.pl | +----+--------------+--------------------+-----------+--------------+
4 rows in set (0.00 sec) |
Jak widać wszystko, do dodawaliśmy, jest zapisane w naszej bazie danych. Znak * użyty zamiast listy pól oznacza, że chcemy wybrać wszystkie dostępne pola tabeli.
Spróbujmy teraz napisać takie polecenie SELECT, które poda nam tylko numery id i imiona:
mysql> SELECT id, imie FROM ksiazka_adresowa; +----+--------------+ | id | imie | +----+--------------+ | 1 | Jan | | 2 | | | 3 | <podaj imie> | | 4 | <podaj imie> | +----+--------------+
4 rows in set (0.00 sec) |
Możesz oczywiście podrać tylko jedną kolumnę, na przykład tę zawierającą numery id:
mysql> SELECT id FROM ksiazka_adresowa; +----+ | id | +----+ | 1 | | 2 | | 3 | | 4 | +----+
4 rows in set (0.06 sec) |
A może chciałbyś wybrać maksymalną wartość, jaka znajduje się w kolumnie id? Do tego celu przydatna jest funkcja MAX():
mysql> SELECT MAX(id) FROM ksiazka_adresowa; +---------+ | MAX(id) | +---------+ | 4 | +---------+
1 row in set (0.00 sec) |
Minimalną wartość pobiera się analogicznie, tylko za pomocą funkcji MIN():
mysql> SELECT MIN(id) FROM ksiazka_adresowa; +---------+ | MIN(id) | +---------+ | 1 | +---------+
1 row in set (0.00 sec) |
Możesz również podrać łączną liczbę rekordów za pomocą funcki COUNT():
mysql> SELECT COUNT(*) FROM ksiazka_adresowa; +----------+ | COUNT(*) | +----------+ | 4 | +----------+
1 row in set (0.00 sec) |
Sumę wartości pól podanej kolumny można opdbać za pomocą funkcji SUM():
mysql> SELECT SUM(id) FROM ksiazka_adresowa; +---------+ | SUM(id) | +---------+ | 10 | +---------+
1 row in set (0.00 sec) |
Średnią z wartości pol podanej kolumny pobiera się za pomocą funkcji AVG():
mysql> SELECT AVG(id) FROM ksiazka_adresowa; +---------+ | AVG(id) | +---------+ | 2.5000 | +---------+
1 row in set (0.00 sec) |
Warunki
Warunki w zapytaniu SELECT umożliwiają dokładniejsze określanie, jakie rekordy mają zostać wybrane. Możesz wybrać na przykład rekord o numerze id równym 3. Jak zwykle w warunkach możesz używać operatorów porównania. Poniższa tabela przedstawia dostępne operatory dla warunków:
= |
Równość |
<>, != |
Nierówność |
< |
Mniejsze |
> |
Większe |
<= |
Mniejsze równe |
>= |
Większe równe |
Spójrzmy ma przykład wybierający rekord o numerze id równym 3:
mysql> SELECT * FROM ksiazka_adresowa WHERE id = 3; +----+--------------+-------------------+-----------+-------+ | id | imie | adres | telefon | email | +----+--------------+-------------------+-----------+-------+ | 3 | <podaj imie> | ul. Warszawska 15 | 468-34-75 | NULL | +----+--------------+-------------------+-----------+-------+
1 row in set (0.06 sec) |
Możesz oczywiście podawać więcej niż jeden warunek. Do łączenia warunków służą operatory logiczne, takie jak AND i OR:
mysql> SELECT id, imie, telefon FROM ksiazka_adresowa WHERE (id>=2 AND id<4) OR (imie='Jan'); +----+--------------+-----------+ | id | imie | telefon | +----+--------------+-----------+ | 1 | Jan | 888-55-41 | | 2 | | 777-33-84 | | 3 | <podaj imie> | 468-34-75 | +----+--------------+-----------+
3 rows in set (0.05 sec) |
Jak widać na powyższym przykładzie, grupy warunków umieszcza się w nawiasach.
Wyrażenie IN
Zamiast podawać grupy warunków dla wartości, które mogą znaleźć się w grupie wyników, można posłużyć się wyrażeniem IN. Spójrzmy najpierw na przykład wybierania rekordów zawierających numer id równy 1, 2 lub 4:
mysql> SELECT id, adres FROM ksiazka_adresowa WHERE id=1 OR id=2 OR id=4; +----+--------------------+ | id | adres | +----+--------------------+ | 1 | ul. Wrocławska 5 | | 2 | ul Krakowska 16 | | 4 | NULL | +----+--------------------+
3 rows in set (0.00 sec) |
To samo można zapisać znacznie prościej za pomocą wyrażenie IN, które definiuje grupę dopuszczalnych wartości dla pola:
mysql> SELECT id, adres FROM ksiazka_adresowa WHERE id IN(1,2,4); +----+--------------------+ | id | adres | +----+--------------------+ | 1 | ul. Wrocławska 5 | | 2 | ul Krakowska 16 | | 4 | NULL | +----+--------------------+
3 rows in set (0.00 sec) |
Jak widać użycie tego wyrażenia znacznie upraszcza zapytanie SQL.
Wyrażenie BETWEEN
Wyrażenie between (ang: pomiędzy) umożliwia określenie górnego i dolnego zakresu dla wartości pól rekordu. Spójrzmy najpierw na przykład wybierania rekordów o numerach id od 1 do 3 za pomocą standardowego WHERE:
mysql> SELECT id, telefon, email FROM ksiazka_adresowa WHERE id>=1 AND id<=3; +----+-----------+--------------+ | id | telefon | email | +----+-----------+--------------+ | 1 | 888-55-41 | jan@email.pl | | 2 | 777-33-84 | zebra@zoo.pl | | 3 | 468-34-75 | NULL | +----+-----------+--------------+
3 rows in set (0.00 sec) |
A teraz za pomocą wyrażenia BETWEEN:
mysql> SELECT id, telefon, email FROM ksiazka_adresowa WHERE id BETWEEN 1 AND 3; +----+-----------+--------------+ | id | telefon | email | +----+-----------+--------------+ | 1 | 888-55-41 | jan@email.pl | | 2 | 777-33-84 | zebra@zoo.pl | | 3 | 468-34-75 | NULL | +----+-----------+--------------+
3 rows in set (0.00 sec) |
Jak widać, użycie tego wyrażenia znacznie upraszcza zapytanie.
Wyrażenie NOT
Wyrażenie NOT pozwala zanegować wyrażenie takie jak IN czy BETWEEN. Spójrzmy na przykład wybierania rekordów z pominięciem rekordów o id równym 1 i 3:
mysql> SELECT id, imie, adres FROM ksiazka_adresowa WHERE id NOT IN(1,3); +----+--------------+--------------------+ | id | imie | adres | +----+--------------+--------------------+ | 2 | | ul Krakowska 16 | | 4 | <podaj imie> | NULL | +----+--------------+--------------------+
2 rows in set (0.00 sec) |
Spójrzmy jeszcze na przykład wybierania rekordów, których numer id nie zawiera się w przedziale od 2 do 4:
mysql> SELECT id, telefon FROM ksiazka_adresowa WHERE id NOT BETWEEN 2 AND 4; +----+-----------+ | id | telefon | +----+-----------+ | 1 | 888-55-41 | +----+-----------+
1 row in set (0.00 sec) |
Sortowanie
Domyślnie wybrane rekordy są sortowane w takiej kolejności, w jakiej zostały dodane do bazy. Można jednak tą kolejnąć zmienić używając polecenia ORDER BY.
Spójrzmy na przykład wybierający z bazy danych rekordy posortowane według imienia:
mysql> SELECT id, imie, adres FROM ksiazka_adresowa ORDER BY imie; +----+--------------+--------------------+ | id | imie | adres | +----+--------------+--------------------+ | 2 | | ul Krakowska 16 | | 3 | <podaj imie> | ul. Warszawska 15 | | 4 | <podaj imie> | NULL | | 1 | Jan | ul. Wrocławska 5 | +----+--------------+--------------------+
4 rows in set (0.00 sec) |
Kolejność rekordów zmieniła się, co najlepiej uwidacznia kolumna z numerami id. Spróbujmy jeszcze posortować rekordy według dwu pól: imienia i adresu:
mysql> SELECT id, imie, adres FROM ksiazka_adresowa ORDER BY imie, adres; +----+--------------+--------------------+ | id | imie | adres | +----+--------------+--------------------+ | 2 | | ul Krakowska 16 | | 4 | <podaj imie> | NULL | | 3 | <podaj imie> | ul. Warszawska 15 | | 1 | Jan | ul. Wrocławska 5 | +----+--------------+--------------------+
4 rows in set (0.00 sec) |
Jak widać, wyniki zostały posortowane według imienia, a te, które miały taką samą wartość w tym polu, zostały dodatkowo posortowane według pola adres.
Możesz wpływać na kierunek sortowania za pomocą słów kluczowych ASC (domyślnie) i DESC (kirunek odwrotny). Spróbujmy zatem posortować numery id w odwrotnej kolejności:
mysql> SELECT id, imie, adres FROM ksiazka_adresowa ORDER BY id DESC; +----+--------------+--------------------+ | id | imie | adres | +----+--------------+--------------------+ | 4 | <podaj imie> | NULL | | 3 | <podaj imie> | ul. Warszawska 15 | | 2 | | ul Krakowska 16 | | 1 | Jan | ul. Wrocławska 5 | +----+--------------+--------------------+
4 rows in set (0.00 sec) |
Słowo kluczowe DISTINCT
Czasem zachodzi potrzeba, aby wśród podanych w jednej kolumnie wyników zapytania nie powtarzały się wartości. Do tego celu służy słowo kluczowe DISTINCT.
Spójrzmy najpierw na normalne wybieranie wartości kolumny imie:
mysql> SELECT imie FROM ksiazka_adresowa; +--------------+ | imie | +--------------+ | Jan | | | | <podaj imie> | | <podaj imie> | +--------------+
4 rows in set (0.00 sec) |
Jak widać wartość '<podaj imie>' występuje dwa razy. Spójrzmy teraz na wynik po użyciu słowa kluczowego DISTINCT:
mysql> SELECT DISTINCT imie FROM ksiazka_adresowa; +--------------+ | imie | +--------------+ | Jan | | | | <podaj imie> | +--------------+
3 rows in set (0.00 sec) |
Jak widać wartości się już nie powtarzają.
Porównanie LIKE
Porównanie LIKE umożliwia tworzenie wzorców w zapytaniach. Spójrzmy na przykład wybierający pozycję w których pole imie na wartość '<podaj imie>', za pomocą typowego warunku WHERE:
mysql> SELECT id, imie FROM ksiazka_adresowa WHERE imie='<podaj imie>'; +----+--------------+ | id | imie | +----+--------------+ | 3 | <podaj imie> | | 4 | <podaj imie> | +----+--------------+
2 rows in set (0.00 sec) |
A teraz za pomocą porównania LIKE:
mysql> SELECT id, imie FROM ksiazka_adresowa WHERE imie LIKE '<%>'; +----+--------------+ | id | imie | +----+--------------+ | 3 | <podaj imie> | | 4 | <podaj imie> | +----+--------------+
2 rows in set (0.00 sec) |
Jak widać, wynik jest ten sam, a możliwości większe. Znak % zonacza dowolny ciąg znaków, natomiast znak _ oznacza dokładnie jeden znak:
mysql> SELECT id, imie, adres FROM ksiazka_adresowa WHERE imie LIKE '_an'; +----+------+------------------+ | id | imie | adres | +----+------+------------------+ | 1 | Jan | ul. Wrocławska 5 | +----+------+------------------+
1 row in set (0.00 sec) |
Porcjowanie wyników zapytania
Jeżeli nie interesują cię wszystkie rekordy pasujące do zapytania, a na przykład jedynie pierwsze 10, możesz posłużyć się klauzulą LIMIT.
Spójrzmy na przykład wybierający z naszej książki adresowej tylko pierwsze dwa rekordy:
mysql> SELECT id, imie, adres FROM ksiazka_adresowa LIMIT 2; +----+------+------------------+ | id | imie | adres | +----+------+------------------+ | 1 | Jan | ul. Wrocławska 5 | | 2 | | ul Krakowska 16 | +----+------+------------------+
2 rows in set (0.00 sec) |
Jak widać, aby zaznaczyć, że chcesz otrzymać określoną liczbę rekordów, powinieneś posłużyć się klauzylą LIMIT, po której podasz odpowiednią wartość.
Spójrzmy na przykład pobierania dwóch rekordów, począwszy od drugiego (dla MySQL-a będzie to jednak rekord 1, ponieważ tutaj rekordy liczy się, zaczynając od zera):
mysql> SELECT id, imie, adres FROM ksiazka_adresowa LIMIT 1,2; +----+--------------+--------------------+ | id | imie | adres | +----+--------------+--------------------+ | 2 | | ul Krakowska 16 | | 3 | <podaj imie> | ul. Warszawska 15 | +----+--------------+--------------------+
2 rows in set (0.00 sec) |
Jak widać z powyższego przykładu, aby pobrać określoną liczbę rekordów, począwszy od ustalonego, podajemy po przecinku numer rekordu początkowego i liczbę rekordów z zbiorze zapytania.
Pierwszy przykład pobierania dwóch rekordów można również zapisać, podając rekord, od którego ma się zacząć pobieranie wyników (czyli podamy zera jako pozycję pierwszego rekordu):
mysql> SELECT id, imie, adres FROM ksiazka_adresowa LIMIT 0,2; +----+------+------------------+ | id | imie | adres | +----+------+------------------+ | 1 | Jan | ul. Wrocławska 5 | | 2 | | ul Krakowska 16 | +----+------+------------------+
2 rows in set (0.00 sec) |
MODYFIKACJA REKORDÓW
Zauważyłeś pewnie że pozycja dodana jako druga, po skrócie 'ul' nie zawiera kropki. Spróbujmy teraz to poprawić za pomocą polecenia UPDATE. Składnia tego polecenia przedstawia się następująco:
UPDATE <nazwa_bazy>.<nazwa_tabeli> SET <nazwa_pola> = 'wartość' WHERE <warunek> |
lub
UPDATE <nazwa_tabeli> SET <nazwa_pola> = 'wartość' WHERE <warunek> |
jeżeli wcześniej zostało użyte polecenie use <nazwa_bazy>.
Spróbujmy zatem poprawić wartość pola adres, które ma id numer 2:
mysql> UPDATE ksiazka_adresowa SET adres = 'ul. Krakowska 16' WHERE id = 2; |
Spójrzmy teraz na rekord o numerze id równym 2:
mysql> SELECT * FROM ksiazka_adresowa WHERE id = 2; +----+------+------------------+-----------+--------------+ | id | imie | adres | telefon | email | +----+------+------------------+-----------+--------------+ | 2 | | ul. Krakowska 16 | 777-33-84 | zebra@zoo.pl | +----+------+------------------+-----------+--------------+
1 row in set (0.00 sec) |
USUWANIE REKORDÓW
Na koniec zajmiemy się usuwaniem rekordów, Służy do tego celu polecenie DELETE, którego składnia przedstawia się następująco:
DELETE FROM <nazwa_bazy>.<nazwa_tabeli> WHERE <warunek> |
lub
DELETE FROM <nazwa_tabeli> WHERE <warunek> |
jeżeli wcześniej zostało użyte polecenie use <nazwa_bazy>.
Jeżeli warunek WHERE ... nie zostanie podany, zawartość całej tabeli zostanie usunięta.
Spróbujmy teraz usunąć rekord o id równym 3:
mysql> DELETE FROM ksiazka_adresowa WHERE id = 3; |
I spójrzmy jak teraz wygląda zawartość naszej tabeli 'ksiazka_adresowa':
mysql> SELECT * FROM ksiazka_adresowa; +----+--------------+--------------------+-----------+--------------+ | id | imie | adres | telefon | email | +----+--------------+--------------------+-----------+--------------+ | 1 | Jan | ul. Wrocławska 5 | 888-55-41 | jan@email.pl | | 2 | | ul. Krakowska 16 | 777-33-84 | zebra@zoo.pl | | 4 | <podaj imie> | NULL | 471-84-36 | my@email.pl | +----+--------------+--------------------+-----------+--------------+
3 rows in set (0.00 sec) |
Jak widać, wartości numerów id nie przeindeksowały się (pole auto_increment), a następny numer id, jaki zostanie dodany, będzie miał wartość o jeden większą od największego, czyli 5.
UŻYTKOWNICY I UPRAWNIENIA
Ta część kursy przybliży ci temat określania uprawnień dla użytkowników bazy danych
System uprawnień w MySQL-u pozwala na dokładne zdefiniowanie praw dostępu do określonej bazy, tabeli czy kolumny.
JAK TO DZIAŁA
System uprawnień MySQL-a opiera się na pięciu tabelach znajdujących się w bazie mysql. Poniższy przykład prezentuje ich nazwy:
mysql> use mysql +-----------------+ | Tables_in_mysql | +-----------------+ | columns_priv | | db | | host | | tables_priv | | user | +-----------------+
5 rows in set (0.05 sec) |
Każda z tych tabel określa uprawnienia użytkownika na innym poziomie dostępu. Tabela db określa dostęp do bazy danych, host definiuje dostęp danych hostów do baz danych, user określa użytkowników całego serwera bazy danych, a tabele tables_priv i columns_priv określają uprawnienia odpowiednio do tabel i do ich kolumn.
TABELA USER
Przyjrzyjmy się teraz bliżej tabeli user, która definiuje użytkowników i ich uprawnienia w naszym systemie. Najpierw spójrzmy na strukturę tej tabeli:
mysql> describe user; +-----------------+---------------+------+-----+-----+-------+-------+ | Field | Type | Null | Key | ()* | Extra | ()** | +-----------------+---------------+------+-----+-----+-------+-------+ | Host | char(60) | | PRI | | | ()*** | | User | char(16) | | PRI | | | ()*** | | Password | char(16) | | | | | ()*** | | Select_priv | enum('N','Y') | | | N | | ()*** | | Insert_priv | enum('N','Y') | | | N | | ()*** | | Update_priv | enum('N','Y') | | | N | | ()*** | | Delete_priv | enum('N','Y') | | | N | | ()*** | | Create_priv | enum('N','Y') | | | N | | ()*** | | Drop_priv | enum('N','Y') | | | N | | ()*** | | Reload_priv | enum('N','Y') | | | N | | ()*** | | Shutdown_priv | enum('N','Y') | | | N | | ()*** | | Process_priv | enum('N','Y') | | | N | | ()*** | | File_priv | enum('N','Y') | | | N | | ()*** | | Grant_priv | enum('N','Y') | | | N | | ()*** | | References_priv | enum('N','Y') | | | N | | ()*** | | Index_priv | enum('N','Y') | | | N | | ()*** | | Alter_priv | enum('N','Y') | | | N | | ()*** | +-----------------+---------------+------+-----+-----+-------+-------+
17 rows in set (0.11 sec) |
Jak widać ta tabela zawiera pola dla nazwy hosta i użytkownika, hasła oraz listę pól z wartościami N lub Y dla określonych praw.
Spójrzmy co zawiera ta tabela:
mysql> select * from user; +-----------+------+----------+-------------+-------------+-------------+ -------------+-------------+-----------+-------------+---------------+ --------------+-----------+------------+-----------------+------------+ ------------+ | Host | User | Password | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv | +-----------+------+----------+-------------+-------------+-------------+ -------------+-------------+-----------+-------------+---------------+ --------------+-----------+------------+-----------------+------------+ ------------+ | localhost | root | | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | % | | | N | N | N | N | N | N | N | N | N | N | N | N | N | N | | localhost | | | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | | % | root | | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | +-----------+------+----------+-------------+-------------+-------------+ -------------+-------------+-----------+-------------+---------------+ --------------+-----------+------------+-----------------+------------+ ------------+
4 rows in set (0.11 sec) |
Jak widać, tabela user zawiera cztery wpisy:
użytkownik root może zalogować się z localhost, nie podaje hasła, ma uprawnienia do każdej operacji. To właśnie jako ten użytkownik cały czas pracujemy, logując się komendą mysql -u root,
użytkownik bez zdefiniowanej nazwy, z dowolnego hosta (znak '%' oznacza dowolny adres hosta), nie ma żadnych uprawnień, nie podaje hasła,
użytkownik bez zdefiniowanej nazwy, z localhost, ma podobnie jak root wszelkie uprawnienia, nie podaje hasła,
użytkownik root może zalogować się z dowolnego hosta, nie podaje hasła, ma uprawnienia do każdej operacji.
TABELA DB
Przyjrzyjmy się teraz bliżej tabeli db, która określa dostęp do bazy danych. Najpierw spójrzmy na strukturę tej tabeli:
mysql> describe db; +-----------------+---------------+------+-----+-----+-------+-------+ | Field | Type | Null | Key | ()* | Extra | ()** | +-----------------+---------------+------+-----+-----+-------+-------+ | Host | char(60) | | PRI | | | ()*** | | Db | char(64) | | PRI | | | ()*** | | User | char(16) | | PRI | | | ()*** | | Select_priv | enum('N','Y') | | | N | | ()*** | | Insert_priv | enum('N','Y') | | | N | | ()*** | | Update_priv | enum('N','Y') | | | N | | ()*** | | Delete_priv | enum('N','Y') | | | N | | ()*** | | Create_priv | enum('N','Y') | | | N | | ()*** | | Drop_priv | enum('N','Y') | | | N | | ()*** | | Grant_priv | enum('N','Y') | | | N | | ()*** | | References_priv | enum('N','Y') | | | N | | ()*** | | Index_priv | enum('N','Y') | | | N | | ()*** | | Alter_priv | enum('N','Y') | | | N | | ()*** | +-----------------+---------------+------+-----+-----+-------+-------+
13 rows in set (0.11 sec) |
Jak widać, tabela ta zawiera pola dla nazwy hosta, bazy danych i użytkownika oraz listę pól z wartościami N lub Y dla określonych praw.
Spójrzmy co już zawiera ta tabela:
mysql> select * from user; +-----------+-------+------+-------------+-------------+-------------+ -------------+-------------+-----------+------------+-----------------+ ------------+------------+ | Host | Db | User | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv | Index_priv | Alter_priv | +-----------+-------+------+-------------+-------------+-------------+ -------------+-------------+-----------+------------+-----------------+ ------------+------------+ | % | test% | | Y | Y | Y | Y | Y | Y | N | Y | Y | Y | +-----------+-------+------+-------------+-------------+-------------+ -------------+-------------+-----------+------------+-----------------+ ------------+------------+
1 row in set (0.00 sec) |
Jak widać, tabela db zawiera jeden wpis:
użytkownik bez nazwy, ma dostęp z każdego hosta do tabeli test.
TABELA HOST
Przyjrzyjmy się teraz bliżej tabeli host, która dokładniej definiuje przywileje zawarte w tabeli db. Najpierw spójrzmy na strukturę tej tabeli:
mysql> describe host; +-----------------+---------------+------+-----+-----+-------+-------+ | Field | Type | Null | Key | ()* | Extra | ()** | +-----------------+---------------+------+-----+-----+-------+-------+ | Host | char(60) | | PRI | | | ()*** | | Db | char(64) | | PRI | | | ()*** | | Select_priv | enum('N','Y') | | | N | | ()*** | | Insert_priv | enum('N','Y') | | | N | | ()*** | | Update_priv | enum('N','Y') | | | N | | ()*** | | Delete_priv | enum('N','Y') | | | N | | ()*** | | Create_priv | enum('N','Y') | | | N | | ()*** | | Drop_priv | enum('N','Y') | | | N | | ()*** | | Grant_priv | enum('N','Y') | | | N | | ()*** | | References_priv | enum('N','Y') | | | N | | ()*** | | Index_priv | enum('N','Y') | | | N | | ()*** | | Alter_priv | enum('N','Y') | | | N | | ()*** | +-----------------+---------------+------+-----+-----+-------+-------+
12 rows in set (0.05 sec) |
Jak widać, tabela ta zawiera pola dla nazwy hosta i bazy danych oraz listę pól z wartościami N i Y dla określonych praw.
Spójrzmy co już zawiera ta tabela:
mysql> select * from host; |
Jak widać, tabela host nie zawiera żadnych wpisów, ponieważ nie były jeszcze potrzebne tak dokładnie określone uprawnienia dostępu.
TABELA TABLES_PRIV
Przyjrzyjmy się teraz bliżej tabeli tables_priv, która definiuje przywileje dostępu do określonych tabel, podobnie jak tabela db do baz danych. Najpierw spójrzmy na jej strukturę:
mysql> describe tables_priv; +-----------------+---------------+------+-----+------+-------+-------+ | Field | Type | Null | Key | ()* | Extra | ()** | +-----------------+---------------+------+-----+------+-------+-------+ | Host | char(60) | | PRI | | | ()*** | | Db | char(64) | | PRI | | | ()*** | | User | char(16) | | PRI | | | ()*** | | Table_name | char(64) | | PRI | | | ()*** | | Grantor | char(77) | | | | | ()*** | | Timestamp | timestamp(14) | YES | | NULL | | ()*** | | Table_priv | Patrz 1) | | | | | ()*** | | Column_priv | Patrz 2) | | | | | ()*** | +-----------------+---------------+------+-----+------+-------+-------+
8 rows in set (0.08 sec) |
Jak widać, tabela ta zawiera pola dla nazwy hosta, bazy danych, użytkownika, tabeli i użytkownika nadającego przywilej oraz pola przeznaczone do określania uprawnień dostępu.
Spójrzmy co zawiera ta tabela:
mysql> select * from tables_priv; |
Jak widać, tabela host nie zawiera żadnych wpisów, ponieważ nie były potrzebne tak dokładnie określone uprawnienia dostępu.
TABELA COLUMNS_PRIV
Przyjrzyjmy się teraz bliżej tabeli columns_priv, która definiuje przywileje dostępu do określonych kolumn w tabelach. Najpierw spójrzmy na strukturę tej tabeli:
mysql> describe columns_priv; +-------------+---------------+------+-----+------+-------+-------+ | Field | Type | Null | Key | ()* | Extra | ()** | +-------------+---------------+------+-----+------+-------+-------+ | Host | char(60) | | PRI | | | ()*** | | Db | char(64) | | PRI | | | ()*** | | User | char(16) | | PRI | | | ()*** | | Table_name | char(64) | | PRI | | | ()*** | | Column_name | char(64) | | PRI | | | ()*** | | Timestamp | timestamp(14) | YES | | NULL | | ()*** | | Column_priv | Patrz 1) | | | | | ()*** | +-------------+---------------+------+-----+------+-------+-------+
7 rows in set (0.00 sec) |
Jak widać, tabela ta zawiera pola dla nazwy hosta, bazy danych, użytkownika, tabeli i nazwy kolumny oraz pole przeznaczone do określania uprawnień dostępu.
Spójrzmy co już zawiera ta tabela:
mysql> select * from columns_priv; |
Jak widać, tabela columns_priv nie zawiera żadnych wpisów, ponieważ nie były jeszcze potrzebne tak dokładnie określone uprawnienia dostępu.
MANIPULACJA UPRAWNIENIAMI
Po dłuższym wstępie przejdźmy do nieco ciekawszej części, czyli nadawania uprawnień i ich odbierania. Wszelkie zmiany dotyczące tabel w bazie mysql możesz przeprowadzać za pomocą znanych ci z poprzedniej części kursy poleceń, takich jak select, insert, update czy delete. Możesz również w łatwy sposób zarządzać uprawnieniami za pomocą poleceń GRANT (dodawanie uprawnień) i REVOKE (odbieranie uprawnień).
Na początku ustawmy hasło dla użytkownika root, aby nikt niepowołany nie mógł w łatwy sposób dostać się do serwera baz danych:
mysql> UPDATE user SET Password=PASSWORD('pass') WHERE user='root'; |
Za pomocą polecenia UPDATE zmieniliśmy wartość pola Password na nowe hasło, tam gdzie użytkownik jest zdefiniowany jako root (dwa rekordy). Hasła w MySQL kodowane są za pomocą funkcji PASSWORD(), dlatego musisz jej użyć, aby zapisać hasło w tabeli.
Ostatnie polecenie (FLUSH PRIVILEGES;) przeładowuje uprawnienia. Gdybyśmy tego nie zrobili, zmiany nie byłyby widoczne, root dalej logowałby się bez hasła. Nie musisz odświeżać uprawnień, jeżeli używasz wbudowanych funkcji do obsługi przywilejów:
mysql> SET PASSWORD FOR root=PASSWORD('mypass'); |
Spróbujmy teraz zalogować się do mysql-a z hasłem 'pass':
C:\apache\mysql\bin> mysql -u root -p |
Jak widać hasło 'pass' nie jest już aktualne, ponieważ zmieniliśmy je na 'mypass' za pomocą funkcji SET PASSWORD...
Spróbujmy zatem jeszcze raz, tym razem podając haslo 'mypass':
C:\apache\mysql\bin> mysql -u root -p |
I spróbujmy jeszcze zalogować się bez hasła, jak dawniej:
C:\apache\mysql\bin> mysql -u root |
Jak wiadć, nasz MySQL jest zabezpieczony hasłem.
Polecenie GRANT
Za pomocą tego polecenia dodajesz uprawnienia dostępu do baz danych, tabel czy kolumn.
Spróbujmy teraz utworzyć nowego użytkownika admin z dostępem do bazy danych nasza_baza i tabeli ksiazka_adresowa:
mysql> GRANT SELECT ON nasza_baza.ksiazka_adresowa TO admin@localhost; |
Mamy już w tej chwili dostępnego użytkownika admin, który ma prawo wybierać dane z tabeli ksiazka_adresowa z naszej bazy. Ten użytkownik nie ma ustawionego hasła, ale musi logować się z localhost:
c:\apache\mysql\bin> mysql -u admin |
Jak widać, nowy użytkownik może się już zalogować. Przetestujmy teraz jego uprawnienia, najpierw na bazie mysql, potem na nasza_baza:
mysql> use mysql |
Jak wynika z powyższego przykładu, nasz nowy użytkownik nie ma dostępu do bazy mysql. Nie może również dodawać rekordów do tabeli ksiazka_adresowa w naszej bazie. Jedynie polecenie SELECT zostało zakończone sukcesem, bo tylko do tego ma uprawnienia użytkownik admin.
Spróbujmy utworzyć teraz użytkownika admin2 z uprawnieniami do wybierania, dodawania, edycji i usuwania rekordów:
mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON nasza_baza.* TO admin2@localhost; |
Ten użtykownik ma prawo do wykonywania instrukcji SELECT, INSERT, UPDATE i DELETE na wszystkich tabelach w bazie nasza_baza. Znak * użyty zamiast nazwy tabeli oznacza dostęp do wszystkich tabel.
admin3 z prawem dodawania rekordów we wszystkich bazach danych systemu:
mysql> GRANT INSERT ON *.* TO admin3@localhost; |
Jak widać, aby zaznaczyć wszystkie bazy danych wraz z towarzyszącymi im tabelami, użyliśmy konstrukcji *.*, co oznacza <dowolna_baza>.<dowolna_tabela>:.
Spróbujmy teraz utworzyć użytkownika admin4 przychodzącego z dowolnego hosta z prawem wybierania rekordów z bazy nasza_baza i dowolnej tabeli:
mysql> GRANT SELECT ON nasza baza.* TO admin4@'%'; |
Jak widać, aby oznaczyć dowolny host, użyliśmy znaku % umieszczonego w cudzysłowach.
Spróbujmy teraz utworzyć użytkownika admin5 ze wszystkimi prawami w bazie nasza_baza i dowolnej tabeli przychodzącego z localhost:
mysql> GRANT ALL PRIVILEGES ON nasza_baza.* TO admin5@localhost; |
Jak widać, aby zaznaczyć, że chcemy nadać użytkownikowi wszystkie prawa, użyliśmy polecenia ALL PRIVILEGES.
Spróbujmy jeszcze utworzyć takiego użytkownika jak poprzedni, ale z prawem nadawania uprawnień (grantów):
mysql> GRANT ALL PRIVILEGES ON nasza_baza.* TO admin6@localhost WITH GRANT OPTION; |
Jak widać, aby zaznaczyć, że chchcemy nadać wszystkie prawa razem z grantami, użyliśmy polecenia WITH GRANT OPTION.
Spróbujmy teraz utworzyć użytkownika admin7 z dostępem do wszystkich baz danych i tabel, ale z wymaganym hasłem 'haslo':
mysql> GRANT ALL PRIVILEGES ON *.* TO admin7@localhost IDENTIFIED BY 'haslo'; |
Spróbujmy teraz zalogować się na użytkownika admin7, raz bez podania hasła, a następnie z hasłem:
C:\apache\mysql\bin> mysql -u admin7 |
Jak widać hasło dla tego użytkownika jest wymagane.
Spróbujmy jeszcze utworzyć użytkownika admin8 z prawem wybierania pola imie oraz edycji pól adres i email z tabeli ksiazka_adresowa w naszej baze testowej:
mysql> GRANT SELECT(imie),UPDATE(adres,email) ON nasza_baza.ksiazka_adresowa TO admin8@localhost; |
Jak widać, aby określić kolumny, na jakich mają działać uprawnienia, wystarczy zapisać je w nawiasach okrągłych występujących po uprawnieniu.
Polecenie REVOKE
Za pomocą tego polecenia usuwasz uprawnienia dostępu do baz danych, tabel czy kolumn.
Spróbujmy teraz usunąć uprawnienia nadane użytkownikowi admin z dostępem do bazy danych nasza_baza i tabeli ksiazka_adresowa:
mysql> REVOKE SELECT ON nasza_baza.ksiazka_adresowa FROM admin@localhost; |
Jak widać z powyższego przykładu, aby usunąć uprawnienia nadane użytkownikowi, posługujemy się podobną składnią jak przy dodawaniu uprawnień. Różnice są dwie: zamiast słowa GRANT występuje REVOKE, a zamiast TO - FROM.
Spróbujmy sprawdzić, czy rzeczywiście nie mamy dostępu do bazy danych nasza_baza:
C:\apache\mysql\bin> mysql -u admin |
Na koniec spróbujmy jeszcze odebrać uprawnienia użytkownikowi admin8:
mysql> REVOKE SELECT(imie),UPDATE(adres,imie) ON nasza_baza.ksiazka_adresowa FROM admin8@localhost; |
52