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 znalezć 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 wejdz 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. Znajdz 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 . a następnie, aby plik index z nowym rozszerzeniem był traktowany jako domyślny plik katalogu, w sekcji DirectoryIndex dopisać: DirectoryIndex index. 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: " " i ?> " " <% 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 PRZYKAADOWY SKRYPT PHP W celu przedstawienia podstawowych cech PHP zostanie zaprezentowany i omówiony przykładowy skrypt odpowiedzialny za wyświetlenie na stronie aktualnej daty.
Skrypt PHP
/* skrypt PHP drukowanie aktualnej daty */ $aktualna_data = date("d-m-Y"); // pobieramy datę do zmiennej echo("Dziś jest $aktualna_data"); // drukujemy linię #koniec drukowania aktualnej daty
Wynikiem działania tego skryptu będzie:
Skrypt PHP
Dziś jest: 27-07-2001
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ć:
Skrypt PHP
Dziś jest: $aktualna_data
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
echo("jakiś tekst"); // drukowanie tekstu echo("jakiś tekst"); # drukowanie tekstu ?> 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:
$zmienna = 19; // liczba dziesiętna dodatnia $zmienna = -5; // liczba dziesiętna ujemna $zmienna = 0145; // liczba ósemkowa (w systemie dziesiętnym 101) $zmienna = 0x19; // liczba szesnastkowa (w systemie dziesiętnym 25) ?> Liczby zmiennoprzecinkowe Liczby zmiennoprzecinkowe zawierają część dziesiętną. W PHP zapisuje się je w sposób następujący:
$zmienna = 1.234; $zmienna = 1.2e3; ?> Aańcuchy znaków Aań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ć.
# deklaracja łańcucha $string = "tekst łańcucha znaków"; # dodanie do zmiennej $string nowego łańcucha $string = $string . " dodany łańcuch"; # przypisanie do zmiennej $string wartości 'pozycja 17' $liczba = 17; $string = "Pozycja: $liczba"; # pobranie pierwszej litery tekstu $string = "dowolny tekst"; $pierwsza_litera = $string[0]; // zmienna $pierwsza_litera jest równa 'd' # b i li t likó kt l k t l d i j $li t lik
# drukowanie z użyciem znaków \n echo("pierwsza linia\n"); echo("druga linia\n"); ?> zwróci: Pierwsza linia druga linia Znaki nowej linii (\n) nie będą interpretowane przez przeglądarkę jako łamanie wiersza, w HTML-u bowiem stosuje się znacznik
. Wprowadzone przejścia do nowej linii będą widoczne natomiast w kodzie zró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:
# drukowanie z użyciem znaków \n i
echo("pierwsza linia \n"); echo("druga linia \n"); ?> Pozwyższy kod zwróci do przeglądarki następujący tekst: Pierwsza linia
druga linia
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 (\).
# cudzysłowy proste echo('znak " oznacza cudzysłów'); ?> Kod ten zwróci: Znak " oznacza cudzysłów Spróbujmy teraz napisać to samo, ale z użyciem podwójnego cudzysłowu:
# cudzysłowy podwójne echo("znak \" oznacza cudzysłów\n"); ?> 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 on line Wybrane znaki specjalne: \n - nowa linia \r - powrót karetki \t - tabulator \\ - backslash \$ - znak dolara \" - cudzysłów podwójny 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). Aań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).
$zmienna = 2 + "14.8"; // zmienna jest równa 16.8 (liczba zmiennoprzecinkowa) $zmienna = 1 + "-1.3e3"; // zmienna jest równa -1299 (liczba zmiennoprzecinkowa) $zmienna = 5 + "tekst-15"; // zmienna jest równa 5 (liczba całkowita) $zmienna = 7 + "10 linii tekstu"; // zmienna jest równa 17 (liczba całkowita) $zmienna = "12.0 linii " + 3; // zmienna jest równa 15 (liczba całkowita) $s="Jestem 'stringiem w pojedynczym cudzysłowie' wewnątrz podwójnego cudzysłowu "; $s='Jestem "stringiem w podwójnym cudzysłowie" wewnątrz pojedynczego 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"; echo($file); // wyświetli c:windowssystem.ini $file = "c:\\windows\\system.ini"; echo($file); // wyświetli 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 = <<
Feedback form
Feedback form
ENDH; Aączenie stringów. Stringi mogą być łączone poprzez operator (.). $first_name = 'Charlie'; $last_name = 'Brown'; $full_name = $first_name . $last_name; 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 = '
'; 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: 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"; echo "value = $a[$i]"; 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]; echo 'value = ' . $this->var; 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; echo "value = {$var}"; // wyświetli "value = 3" echo "value = \{$var}"; // wyświetli "value = {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"; $sql = "select * from users where last_name = '" . addslashes($last_name) . "'"; 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 = ''.$link.''; $html = "$link"; 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:
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 echo $a['apple']; function tree($type = apple) function tree($type = 'apple') 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'; $str2 = 'def'; if (!strcmp($str1, $str2)) { // zapamiętaj że funkcja strcmp() zwraca zero jeżeli stringi są identyczne } if ($str1 == $str2) { // PHP potrafi porównywać stringi także bezpośrednio } if ($str1 == 'def') { } 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 $str = substr('abcdef', -2, 1); // e 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 $i = strpos('przykładowy string do testowania', 'st', 12); // $i = 23 $s = strstr('przykładowy string do testowania', 'st'); // $s = string do testowania $s = strrchr('przykładowy string do testowania', 'st'); // $s = string $i = strrpos('przykładowy string do testowania', 'st'); // $i = 23 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 $s = sprintf("%01.2f", 1.3 - 0.9); // 0.40 $s = sprintf("%s %s", 'Charlie', 'Brown'); // Charlie Brown 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ądz tekstowego. Tablice jako struktury są tematem następnego rozdziału (rozdział o tablicach).
# indeksy liczbowe $tablica[0] = "element pierwszy o indeksie 0"; $tablica[1] = "element drugi o indeksie 1"; # indeksy tekstowe $inna_tablica["pole1"] = 19; $inna_tablica["pole2"] = 38; 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.
$a = 5; # poprawna nazwa $_zmienna = 5; # poprawna nazwa $9sztuk = 5; # niepoprawna nazwa (cyfra na początku zmiennej) $sztuk9 = 5; # poprawna nazwa $zażółć_gęślą_jazń = 5; # poprawna nazwa (litery i znaki _) // zwyczajowo nie używa się jednak polskich liter w nazwach zmiennych $znak! = 5; # niepoprawna nazwa (niedozwolony znak !) ?> 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.
$zmienna = 5; $zmienna = "tekst"; $zmienna = date("d-m-Y"); ?> 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.
$a = "tekst"; // Zmienna $a nma wartość 'tekst' $b = &$a; // Referencja do $a przez $b $b = "Kolejny $b" // Zmiana zawartości zmiennej $b echo($a); // drukowanie zmienionej zmiennej poprzez zmianę w $b echo("\n"); // drukowanie odstępu echo($b); // drukowanie zmienionej zmiennej $b ?> Powyższy kod zwraca: Kolejny tekst 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 - Odejmowanie * Mnożenie / Dzielenie % Reszta z dzielenia (dzielenie modulo) Przykład dodawania, odejmowania, mnożenia, dzielenia i wyliczania reszty z dzielenia:
# dodawanie $a = 2; $b = 6; $c = $a + $b; echo($c); // zmienna $c ma wartość 8 # odejmowanie $a = 6; $b = 2; $c = $a - $b; echo($c); // zmienna $c ma wartość 4 # mnożnie $ 2 5 8 7 28 14 2 Operatory inkrementacji/dekrementacji Operator Opis ++ Inkrementacja zmiennej (powiększenie jej wartości o 1) -- Dekrementacja zmiennej (pomniejszenie jej wartości o 1)
# inkrementacja $a = 2; $a++; // inkrementacja, równoważne z zapisem $a = $a + 1; echo($a++); // zapisanie nowej wartości po wykonaniu instrukcji echo echo(++$a); // zapisanie nowej wartości przed wykonaniem instrukcji echo echo($a); #dekrementacja $b = 8; $b--; // dekrementacja, równoważne z zapisem $b = $b - 1; echo($b--); // zapisanie nowej wartości po wykonaniu instrukcji echo echo(--$b); // zapisanie nowej wartości przed wykonaniem instrukcji echo echo($b); ?> Powyższy przykład zwraca: 3 5 5 7 5 5 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
$tekst = "kawałek"; echo($tekst); $tekst = $tekst . " tekstu"; echo($tekst); $tekst .= "..."; echo($tekst_; ?> Powyższy przykład zwraca: kawałek kawałek tekstu kawałek tekstu... ZASIG 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.
$zmienna = 5; function druk() { 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 STAAE 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.
define("MOJA_STALA","wartość stałej..."); echo(MOJA_STALA); ?> 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:
phpinfo(); ?> 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.
"); ?> Powyższy przykład wydrukowania tablicy przy użyciu funkcji print_r() i znaczników
i
(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:
# rząd pierwszy (1) $tablica[0][0] = "pole 1-1"; $tablica[0][1] = "pole 1-2"; $tablica[0][2] = "pole 1-3"; # rząd drugi (2) $tablica[1][0] = "pole 2-1"; $tablica[1][1] = "pole 2-2"; $tablica[1][2] = "pole 2-3"; # rząd trzeci (3) $tablica[2][0] = "pole 3-1"; $tablica[2][1] = "pole 3-2"; $tablica[2][2] = "pole 3-3"; ?> 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 ( [0] => Array ( [0] => pole 1-1 [1] => pole 1-2 [2] => pole 1-3 ) [1] => Array ( [0] => pole 2-1 [1] => pole 2-2 [2] => pole 2-3 ) [2] => Array ( [0] => pole 3-1 [1] => pole 3-2 [2] => pole 3-3 ) 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:
if (warunek) # kod, który ma zostać wykonany w przypadku spełnienia warunku ?> 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:
if(warunek) # kod, który ma zostać wykonany w przypadku spełnienia warunku ?> Spójrzmy zatem na przykład instrukcji, która sprawdza, czy zmienna $test jest liczbą większą od zera:
$test = 19; if($test > 0) echo("Podano liczbę większą od zera"); ?> I tak powyższy kod zwróci: Podano liczbę większą od zera Spójrzmy na taki przykład:
$test = -5; if($test > 0) echo("Podano liczbę większą od zera"); echo("Kolejna linia"); ?> 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: { # linia kodu # ... # linia kodu } 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:
$test = -5; if($test > 0) { echo("Podano liczbę większą od zera"); echo("Kolejna linia"); } ?> Teraz powyższy kod nie zwróci niczego, ponieważ zmienna testowa jest mniejsza od zera. Natomiast następujący kod:
$test = 19; if($test > 0) echo("Podano liczbę większą od zera"); echo("Kolejna linia"); ?> zwróci: Podano liczbę większą od zera Kolejna linia Aby zobaczyć, jak warunek if wygląda w praktyce, przypomnijmy sobie formularz do podawania imienia kota z rozdziału o zmiennych: podane imię kota i wykonywać różne czynności dla różnych imion:
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:
Twój kot i jego imię
if($imie_kota == "") { echo(""); } else if ($imie_kota == "Mruczek") { echo("Mruczek?"); } else if ($imie_kota == "Ramzes") { echo("Ramzes!"); } else { echo("Twój kot nazywa się... $imie_kota"); } ?>
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 HTML endif; ?> 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:
Twój kot i jego imię
if($imie_kota == ""): ?>
elseif ($imie_kota == "Mruczek"): ?> Mruczek? $ Blok instrukcji switch zostaje w tym przypadku otwarty za pomocą znaku :, a zakończony instrukcją endswitch. PTLE INSTRUKCJA WHILE Podstawowa struktura pętli while przedstawia się następująco:
while (warunek) # kod pętli ?> 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:
$i = 1; while ($i <= 5) echo "Licznik ma wartość " . $i++ . "\n"; # inkrementacja, zapisanie nowej wartości po wykonaniu instrukcji echo ?> 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 Licznik ma wartość: 2 Licznik ma wartość: 3 Licznik ma wartość: 4 Licznik ma wartość: 5 Zbudujmy teraz taki warunek, który od razu nie jest spełniony:
$i = 6; while ($i <= 5) echo "licznik ma wartość " . $i++ . "\n"; ?> 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:
$i = 1; while ($i <= 5) { echo("Wartość licznika: "); $i++; echo($i); } ?> Co zwróci: Wartość licznika: 2 Wartość licznika: 3 Wartość licznika: 4 Wartość licznika: 5 Wartość licznika: 6 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:
$i = 1; while ($i <= 5): echo("Wartość licznika: "); $i++; echo($i); endwhile; ?> Blok instrukcji while zostaje w tym przypadku otwarty za ponicą znaku :, a zakończony instrukcją endwhile. 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:
for (licznik; warunek; inkrementacja/dekrementacja) # kod pętli ?> 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 speAniony 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:
for ($i=1; $i<=5; $i++) echo("Licznik ma wartość: $i"); ?> Taka konstrukcja zwraca: Licznik ma wartość: 1 Licznik ma wartość: 2 Licznik ma wartość: 3 Licznik ma wartość: 4 Licznik ma wartość: 5 Podobnie jak w pętli while czy w instrukcjach if blok kodu pętli umieszcza się wewnątrz nawiasów klamrowych:
for ($i=1; $i<=5; $i++) { echo("Licznik ma wartość: "); echo($i); } ?> Możliwe jest również stworzenie pętli o zmniejszającym się liczniku od wartości 5 do 1:
for ($i=5; $i<=1; $i--) { echo("Licznik ma wartość: "); echo($i); } ?> Taka pętla zwraca: Licznik ma wartość: 5 Licznik ma wartość: 4 Licznik ma wartość: 3 Licznik ma wartość: 2 Licznik ma wartość: 1 Alternatywny sposób zapisu PHP udostępnia jeszcze jeden sposób zapisu takiej pętli:
for ($i=5; $i<=1; $i--): echo("Licznik ma wartość: "); echo($i); endfor; ?> 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:
foreach ($tablica as $value) # kod pętli ?> PHP udostępnia jeszcze jeden sposób zapisu tej pętli:
$tablica = array( "pole1" => "element1", "pole2" => "element2", "pole3" => "element3" ); echo("Zawartość tablicy: "); foreach ($tablica as $key =>$value): echo "\$tablica[$key] = " . $value . "\n"; endforeach; ?> 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:
for ($i=1;; $i++) { if($i > 5) { break; } else { echo("Licznik ma wartość: "); echo("$i\n"); } } ?> Taki kod zwraca dokładnie to samo, co poprzenie pętle: Licznik ma wartość: 1 Licznik ma wartość: 2 Licznik ma wartość: 3 Licznik ma wartość: 4 Licznik ma wartość: 5 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:
for ($i=1;; $i++) { if($i > 5) { break; } else { echo("Licznik ma wartość: "); echo("$i\n"); } } ?> Taki kod zwraca dokładnie to samo, co poprzenie pętle: Licznik ma wartość: 1 Licznik ma wartość: 2 Licznik ma wartość: 3 Licznik ma wartość: 4 Licznik ma wartość: 5 Instrukcja break może być także używana wewnątrz pętli while. FUNKCJE
test("jeden", "dwa"); echo("\n\n"); test(10, 100); ?> Powyższe wywołania funkcji test() zwracają: Podano następujące argumenty: jeden dwa Podano następujące argumenty: 10 100 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:
function test(&$text) { $text .= " [ten tekst dodała funkcja test()]"; } ?> Wywołanie tej funkcji wygląda następująco:
$text = "to jest piękny tekst"; test($tekst); echo $tekst; ?> 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:
function test($text) { $text .= " [ten tekst dodała funkcja test()"; },br> ?> Wywołanie funkcji test():
$tekst = "To jest piękny tekst"; # tryb normalny test($tekst); echo $tekst . "\n"; # referencja test(&$tekst); echo $tekst . "\n"; ?> Powyższe wywołanie funkcji zwracają: To jest piękny tekst To jest piękny tekst [ten tekst dodała funkcja test()] Domyślne wartości argumentów PHP wspiera obsługę domyślnych wartości argumentów, które nie muszą być wtedy podawane:
function test($argument_1, $argument_2 = "") { echo("Podano następujące argumenty:\n $argument_1\n $argument_2"); } ?> Oto różne wywołanie tej funkcji:
test("jeden", "dwa"); echo "\n\n"; Funkcja ta zwraca liczbę podanych argumentów wywołania funkcji:
function test() { $liczba_argumentow = func_num_args(); echo "Podano $liczba_argumentow argumentów!"; } ?> Przykład wywołania funkcji:
test(1, 2, 3, 4, 5); ?> Wynik działania funkcji: Podano 5 argumentów! func_get_arg Funkcja ta zwraca wartość podanego argumentu wywołania funkcji:
function test() { $liczba_argumentow = func_num_args(); if ($liczba_argumentow >= 3) { $trzeci = func_get_arg(2); echo "Trzeci argument: $trzeci"; } } ?> Przykład wywołania funkcji:
test(1, 2, 3, 4, 5); ?> Wynik działania funkcji: Trzeci argument: 3 func_get_args Funkcja ta zwraca tablicę argumentów wywołania funkcji:
function test() { $liczba_argumentow = func_num_args(); $argumenty = func_get_args(); echo "Podano następujące argumenty:\n foreach($argumenty as $key => $value) { echo " $key) $value\n"; } } ?> Przykład wywołania funkcji:
test("jeden", "dwa", "trzy", "cztery", "pięć"); ?> Wynik działania funkcji: Podano następujące argumenty: 0) jeden 1) dwa 2) trzy 3) cztery 4) pięć 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.
function test(&$text) { $text .= " [ten tekst dodała funkcja test()]"; } ?> Wywołanie tej funkcji wygląda następująco:
$text = "to jest piękny tekst"; test($tekst); echo $tekst; ?> 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:
function test($text) { $text .= " [ten tekst dodała funkcja test()"; },br> ?> Wywołanie funkcji test():
$tekst = "To jest piękny tekst"; # tryb normalny test($tekst); echo $tekst . "\n"; # referencja test(&$tekst); echo $tekst . "\n"; ?> Powyższe wywołanie funkcji zwracają: To jest piękny tekst To jest piękny tekst [ten tekst dodała funkcja test()] Domyślne wartości argumentów PHP wspiera obsługę domyślnych wartości argumentów, które nie muszą być wtedy podawane:
function test($argument_1, $argument_2 = "") { echo("Podano następujące argumenty:\n $argument_1\n $argument_2"); } ?> Oto różne wywołanie tej funkcji:
test("jeden", "dwa"); echo "\n\n"; test(10); ?> Powyższe wywołania funkcji test() zwracają: Podano następujące argumenty: jeden dwa Podano następujące argumenty: 10 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ść):
function test($argument_2 = "", $argument_1) { echo("Podano następujące argumenty:\n $argument 1\n $argument 2"); func_get_arg Funkcja ta zwraca wartość podanego argumentu wywołania funkcji:
function test() { $liczba_argumentow = func_num_args(); if ($liczba_argumentow >= 3) { $trzeci = func_get_arg(2); echo "Trzeci argument: $trzeci"; } } ?> Przykład wywołania funkcji:
test(1, 2, 3, 4, 5); ?> Wynik działania funkcji: Trzeci argument: 3 func_get_args Funkcja ta zwraca tablicę argumentów wywołania funkcji:
function test() { $liczba_argumentow = func_num_args(); $argumenty = func_get_args(); echo "Podano następujące argumenty:\n foreach($argumenty as $key => $value) { echo " $key) $value\n"; } } ?> Przykład wywołania funkcji:
test("jeden", "dwa", "trzy", "cztery", "pięć"); ?> Wynik działania funkcji: Podano następujące argumenty: 0) jeden 1) dwa 2) trzy 3) cztery 4) pięć PRZYKAAD FUNKCJI Napiszemy teraz funkcję, która będzie potrafiła podany tekst umieścić w znacznikach pogrubienia ( i ), podkreślenia ( i ), czy pochylenia ( 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: 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:
class koszyk { var $jablka; function dodaj_jablko($ilosc) { $this -> jablka += $ilosc; } function podaj_jablka() { return ($this -> jablka); } } ?> 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:
# stwórz egzemplarz obiektu $koszyk_1 = new koszyk; ?> Przy odwoływaniu się do metod lub zmiennych posługujemy się operatorem -> występującym po nazwie stworzonego obiektu:
# dodaj pięć jabłek $koszyk_1 -> dodaj_jablko(5); ?> Pełny przykład wykorzystania klasy koszyk został przedstawiony poniżej:
# stwórz egzemplarz obiektu $koszyk_1 = new koszyk; # dodaj pięć jabłek $koszyk_1 -> dodaj_jabko(5); # dodaj jeszcze ilość jabłek w zależności od wartości zmiennej $ilosc $ilosc = 3; $koszyk_1 -> dodaj_jablko($ilosc); # odczytaj ilość jabłek $ile = $koszyk_1 -> podaj_jablka(); echo("Masz $ile jablek w koszyku."); ?> 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, j ki t j i i b i h ł i t j ż li ż d i t i J ż li i d d i k t 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)) $session_id = generate_session_id(); // hipotetyczna funkcja 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: Następna strona Każdy formularz powinien zawierać ukryty argument 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(); echo("$city "); 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(); echo("$city "); session_register('city'); echo("$city "); $city = "Dallas"; 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. Jeżeli odnaleziony został stary identyfikator sesji, PHP odtwarza przypisania do wszystkich zarejestrowanych zmiennych i udostępnia te wartości jako zwykłe zmienne globalne. 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_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ądz 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. imagecharup(int $uchwyt, $czcionka, $x, $y, string $znak, int Rysuje znak pionowo od punktu $x $y, w danym kolorze. $kolor) int imagecolorallocate(int $uchwyt, $red, $green, $blue) Zwraca uchwyt barwy o podanej zawartości kolorów RGB. Kopiuje wycinek z obrazka zródłowego o punkcie początkowym $zrodl_x imagecopyresized(int $uchwyt_docelowy, $uchwyt_zrodlowy, $zrodl_y, szerokości $zrodl_szer i wysokości $zrodl_wys. Następnie wkleja $docel_x, $docel_y, $zrodl_x, $zrodl_y, $docel_szer, do obrazka docelowego zaczynając od punktu $docel_x $docel_y, zmieniając $docel_wys, $zrodl_szer, $zrodl_wys) 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. Rysuje przerywaną linię z punktu $x1 $y1 do punktu $x2 $y2 w podanym imagedashedline(int $uchwyt, $x1, $y1, $x2, $y2, $kolor) kolorze. Zalewa obrazek kolorem z punktu $x $y do pierwszej napotkanej linii tego imagefill(int $uchwyt, $x, $y, $kolor) samego koloru. Rysuje wypełniony kolorem wielokąt. Współrzędne wszystkich punktów są imagefilledpolygon(int $uchwyt, array $tablica_punktow, int zawarte w tablicy punktów, w której indeksy parzyste to współrzędne x $ilosc_punktow, $kolor) wierzchołków wielokąta, a nieparzyste to współrzędne y wierzchołków wielokąta. Rysuje wypełniony kolorem prostokąt, którego lewy-górny wierchołek ma imagefilledrectangle(int $uchwyt, $x1, $y1, $x2, $y2, $kolor) współrzędne $x1 $y1, a prawy-dolny $x2 $y2. Wypełnia rysunek kolorem od punktu $x $y do linii o podanym kolorze - imagefilltoborder(int $uchwyt, $x, $y, $kol_graniczny, $kolor) $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. Aaduje nową czcionkę. Plik z definicją czcionki powinien być wygenerowany int imageloadfont(string $plik) na komputerze z takim samym procesorem, w jaki został wyposażony komputer z interpreterem PHP. Rysuje wielokąt, którego współrzędne wierzchołków są zapisane w formie imagepolygon(int $uchwyt, array $punkty, int $il_punktow, tablicy, gdzie indeksy parzyste to współrzędne x, a indeksy nieparzyste to $kolor) współrzędne y, a ilość wierzchołków jest zapisana jako $il_punktow. Rysuje prostokąt, którego lewy-górny wierzchołek ma współrzędne $x1 $y1, imagerectangle(int $uchwyt, $x1, $y1, $x2, $y2, $kolor) 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 Rysuje łańcuch znaków w podanej czcionce i kolorze, zaczynając od punktu $kolor) $x $y. imagestringup(int $uchwyt, $czcionka, $x, $y, string $lancuch, int Rysuje w pionie łańcuch znaków w podanej czcionce i o podanym kolorze, $kolor) zaczynając od punktu $x $y. int imagesx(int $uchwyt) Zwraca szerokość obrazka int imagesy(int $uchwyt) Zwraca wysokość obrazka Wyświetla tekst przy użyciu czcionki True Type, znajdującej się w pliku imagettftext(int $uchwyt, $wielkosc, $kat, $x, $y, $kolor, string zaczynając od punktu $x $y w podanym kolorze. Jeżeli $kat jest równy 0, to $plik, $tekst) 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. Zwraca indeks koloru, jeżeli nie ma takowego w palecie obrazka zwraca int imagecolorresolve(int $uchwyt, $red, $green, $blue) najbliższy mu. bool imagecolorset(int $uchwyt, $indeks, $red, $green, $blue) Określa kolor podanego indeksu palety Zwraca tablicę asocjacyjną kolorów RGB palety o podanym indeksie. array imagecolorsforindex(int $uchwyt, $indeks) 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. 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); ?> 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 2;Psy;Władysław Pasikowski 3;Ptaki;Alfred Hitchcock 4;Siedem;David Fincher 5;Człowiek z Żelaza;Andrzej Wajda 6;Arizona Dream;Emir Kusturica 7;Chata wuja Toma;Stan Lathan 8;Pulp Fiction;Quentin Tarantino 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 przejdz do katalogu z binariami MySQL-a. Domyślnie jest to katalog c:\apache\mysql\bin: c:\windows>cd .. c:\>cd apache\mysql\bin c:\apache\mysql\bin> 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 Enter password: ******* Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 24 to server version 3.23.22-beta-debug Type 'help' for help. mysql> 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 ISTNIEJCYCH 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) mysql> 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) mysql> 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. drop z odpowiednimi argumentami (w tym przypadku databases i nazwą bazy, którą chcemy usunąć): mysql>drop database test; Query ok, 0 rows affected (0.00 sec) mysql> Sprawdzmy, jakie bazy są teraz dostępne: mysql> show databases; +------------+ | Database | +------------+ | mysql | | nasza_baza | +------------+ 2 rows in set (0.00 sec) mysql> 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ądz 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 . " lub wywołując komendę use . 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 Database changed mysql> WYŚWIETLANIE ISTNIEJCYCH 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 Empty set (0.00 sec) mysql> 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 Database changed mysql> show tables; +-----------------+ | Tables_in_mysql | +-----------------+ | columns_priv | | db | | host | | tables_priv | | user | +-----------------+ 5 rows in set (0.00 sec) mysql> 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 oraz definicją listy pól. Wybrane typy pól są d i iż j 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 dla wylistowania pól tabeli. Sprawdzmy zatem co zwróci teraz polecenie show tables: mysql> show tables; +----------------------+ | Tables_in_nasza_baza | +----------------------+ | adresy | +----------------------+ 1 row in set (0.05 sec) mysql> 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 : mysql> ALTER TABLE adresy ADD adres_email VARCHAR(100); Query OK, 0 rows affected (0.11 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> 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) mysql> * = select,insert,update,references (użyte, aby zapis tabeli był bardziej czytelny) 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); Query OK, 0 rows affected (0.11 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> 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); Query OK, 0 rows affected (0.05 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> 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). Sprawdzmy 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) mysql> * l i d f mysql> DROP TABLE do_usuniecia; Query OK, 0 rows affected (0.00 sec) mysql> Sprawdzmy listę table w naszej bazie: mysql> show tables; +----------------------+ | tables_in_nasza_baza | +----------------------+ | ksiazka_adresowa | +----------------------+ 1 row in set (0.00 sec) mysql> Jak widać wszysko się powiodło i nie ma już tabeli do_usuniecia. W naszej bazie znajduje się jedynie tabela ksiazka_adresowa. JZYK 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'); Query OK, 1 row affected (0.00 sec) mysql> Jak już pewnie zauważyłeś, polecenie dodawania nowego rekordu składa się z następujących części: " INSERT INTO . lub tylko , jeżeli zostało wcześniej wywołane zostało polecenie use , " 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 | | | | | adres | blob | YES | | NULL | | | telefon | varchar(15) | YES | | NULL | | | email | varchar(80) | YES | | NULL | | +----------+-------------+------+-----+--------------+----------------+ 5 rows in set (0.00 sec) mysql> 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 ''. 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'); Query OK, 1 row affected (0.06 sec) mysql> 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'); Query OK, 1 row affected (0.06 sec) mysql> 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: 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 | | | 4 | | +----+--------------+ 4 rows in set (0.00 sec) mysql> 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) mysql> 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) mysql> 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) mysql> 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) mysql> 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) mysql> Ś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) 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) mysql> 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 | | NULL | +----+--------------+--------------------+ 2 rows in set (0.00 sec) mysql> 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) mysql> 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 | | ul. Warszawska 15 | | 4 | | NULL | | 1 | Jan | ul. Wrocławska 5 | +----+--------------+--------------------+ 4 rows in set (0.00 sec) mysql> 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 | | NULL | | 3 | | ul. Warszawska 15 | | 1 | Jan | ul. Wrocławska 5 | +----+--------------+--------------------+ 4 rows in set (0.00 sec) mysql> 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. M ż ł ć ki k i łó kl h ASC (d śl i ) i DESC (ki k d ) 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) mysql> 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 | | ul. Warszawska 15 | +----+--------------+--------------------+ 2 rows in set (0.00 sec) mysql> 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) mysql> 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 . SET = 'wartość' WHERE lub UPDATE SET = 'wartość' WHERE jeżeli wcześniej zostało użyte polecenie use . 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; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> 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 | 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 DZIAAA 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 Database changed mysql> show tables; +-----------------+ | Tables_in_mysql | +-----------------+ | columns_priv | | db | | host | | tables_priv | | user | +-----------------+ 5 rows in set (0.05 sec) mysql> 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) mysql> Objaśnienia: * Default ** Privileges *** select,insert,update,references 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 | Alt i | 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) mysql> Objaśnienia: * Default ** Privileges *** select,insert,update,references 1) set('Select','Insert','Update','Delete','Create','Drop', 'Grant','References','Index','Alter') 2) set('Select','Insert','Update','References') 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; Empty set (0.00 sec) mysql> 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) mysql> Objaśnienia: * Default ** Privileges *** select,insert,update,references 1) set('Select','Insert','Update','References') 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; Empty set (0.00 sec) mysql> 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; Query OK, 0 rows affected (0.00 sec) mysql> 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 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 52 to server version: 3.23.33 Type 'help' for help. mysql> 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 ERROR 1044: Access denied for user: admin@localhost' to database 'mysql' mysql> use nasza_baza Database changed mysql>INSERT INTO ksiazka_adresowa VALUES(0,'Imie','adres','telefon', 'adres@email.pl'); ERROR 1142: insert command denied to user 'admin@localhost' for table 'ksiazka_adresowa' mysql> select * from ksiazka_adresowa; Empty set (0.00 sec) 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; Query OK, 0 rows affected (0.00 sec) mysql> 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; Query OK, 0 rows affected (0.00 sec) mysql> Jak widać, aby zaznaczyć wszystkie bazy danych wraz z towarzyszącymi im tabelami, użyliśmy konstrukcji *.*, co oznacza .:. 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@'%'; Query OK, 0 rows affected (0.00 sec) mysql> 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; Query OK, 0 rows affected (0.00 sec) mysql> Jak widać, aby zaznaczyć, że chcemy nadać użytkownikowi wszystkie prawa, użyliśmy polecenia ALL PRIVILEGES. S ób j j ć ki ż k ik j k d i l d i i ń ( ó ) 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; Query OK, 0 rows affected (0.05 sec) mysql> 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 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 83 to server version: 3.23.33 Type 'help' for help. mysql> use nasza_baza ERROR 1044: Access denied for user: 'admin@localhost' to database 'nasza_baza' mysql> 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; Query OK, 0 rows affected (0.00 sec) mysql>