Kurs PHP & MYSQL


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 %>
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 () 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 = '';
$html .= '';
for($i=0; $i<10; $i++) {
$square = $i * $i;
$html .= '';
}
$html .= '
numbersquare
' . $i . '' . $square . '
';
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:

Po uruchomieniu tego pliku waszym oczom ukaże się masa tabelek zawierających odpowiednią ilość informacji, żeby zaspokoić
nawet najbardziej ciekawskich.
Wnioski:
Znając tyle zmiennych możemy z nich skorzystać na różne sposoby. Możemy po prostu zmieścić bardzo prostą informację na
stronie, która informowała by z jakiej przeglądarki korzysta użytkownik, jaki jest jego adres IP oraz skąd przybywa:
Używasz przeglądarki Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98)
Twój adres IP to 195.117.166.146
Przybyłeś tutaj ze strony http://php.bajo.pl/artykuly.php?id=2
TABLICE
TABLICE JEDNOWYMIAROWE
Tablice jednowymiarowe mogą przechowywać jedną kolumnę danych. Składają się z nazwy tablicy (poprzedzonej znakiem $) i
indeksu podanego w nawiasach kwadratowych ([ i ]).
Tworzenie tablic
Tablice można zainicjować (utworzyć) na dwa sposoby: za pomocą funkcji array() oraz poprzez dopisanie nowego (pierwszego)
elementu.
$tablica = array();
?>
Powyższy kod tworzy nową tablicę, ale bez żadnego elementu. Można jednak od razu przy tworzeniu tablicy zadeklarować jej
elementy:
$tablica = array("element1","element2","element3");
?>
Powyższy przykład tworzy tablicę z już zadeklarowanymi elementami. Elementy oddziela się od siebie za pomocą przecinka, a
łańcuchy znaków umieszcza w cudzysłowach. Natomiast jeżeli wartość liczbowa jest liczbą, nie ma potrzeby umieszczania jej w
cudzysłowach:
$tablica = array(1,2,3);
?>
Domyślnie pierwszy element ma indeks o wartości 0 Jeżeli chcesz, żeby tablica zaczynała się od innego indeksu, musisz użyć
operatora =>.
$tablica = array(1 => "element1","element2","element3");
?>
W podobny sposób możesz utworzyć tablicę z tylko niektórymi indeksami:
$tablica = array(
1 => "element1",
3 => "element2",
5 => "element3"
);
?>
Powyższy przykład różni się trochę w zapisie od poprzedniego, ponieważ zastosowano w nim przejścia do nowej linii i wcięcia,
ale tylko w celu zwiększenia czytelności. Nie wpływa to na naszą tablicę, zapis jest za to o wiele bardziej intuicyjny.
Aby utworzyć tablicę zawierającą indeksy tekstowe możemy również posłużyć się operatorem =>:
$tablica = array(
"pole1" => "element1",
"pole2" => "element2",
"pole3" => "element3"
);
?>
Dodawanie elementów
Dodawanie nowych elementów do tablicy odbywa się poprzez napisanie nazwy tablicy i podanie numeru (indeksu) pozycji, do
której chcemy dopisać nową wartość:
# indeks liczbowy
$tablica[0] = "element1";
$tablica[1] = "element2";
$tablica[2] = "element3";
?>
Jeżeli dodajesz nowe pozycje do tablicy, tak jak w powyższym przykładzie, możesz uprościć nieco zapis, nie podając numerów
indeksów (pisząc samo []). W takim przypadku PHP samo dodaje nowe elementy, poczynając od indeksu o wartości 0. Kolejne
elementy dodawane są zawsze na końcu tablicy:
# tworzenie tablicy z indeksami liczbowymi, które nie są podawane
$tablica[] = "element1";
$tablica[] = "element2";
$tablica[] = "element3";
?>
Możesz rónież dopisywać nowe elementy podając indeksy tekstowe:
# indeks tekstowy
$tablica["jeden"] = "element1";
$tablica["dwa"] = "element2";
$tablica["trzy"] = "element3";
?>
Wyświetlenie danych
Odwoływanie się do tablicy jednowymiarowej wymaga napisania nazwy tablicy oraz podania w nawiasach kwadratowych
indeksu elemantu. Indeks może być liczbą całkowitą lub łańcuchem znaków.
# definicja tablicy
$tablica = array("element1","element2","element3");
# drukowanie elementów od 0 do 2
echo($tablica[0]);
echo($tablica[1]);
echo($tablica[2]);
?>
Powyższy przykład zwraca listę elementów tablicy:
element1
element2
element3
W podobny sposób drukuje się zawartość tablic o indeksach tekstowych.
#definicja tablicy
$tablica = array(
"pole1" => "element1",
"pole2" => "element2",
"pole3" => "element3"
);
# drukowanie elementów od 'pole1' do 'pole3'
echo($tablica["pole1"]);
echo($tablica["pole2"]);
echo($tablica["pole3"]);
?>
Prowyższy przykład zwraca listę elementów tablicy:
element1
element2
element3
Spójrzmy jeszcze na taki przykład:
$tablica = array(1,2,3);
echo($tablica);
?>
Co zwróci w typ przypadku funkcja echo()? Ponieważ nie został podany indeks elementu tablicy, PHP zwróci tylko nazwę typu
zmiennej:
Array
PHP ma wiele funkcji działań na tablicach - od przeglądania po sortowanie. Wszystkie są szczegółowo omówione w manualu
PHP na stronach http://pl.php.net.
Funkcja print_r
Funkcja print_r() jest bardzo wygodna przy debugowaniu skryptu. Drukuje ona zawartość podanej zmiennej z uwzględnieniem
jej struktury.
#definicja tablicy trójelementowej
# dwa indeksy tekstowe i jeden liczbowy
$tablica = array(
"pole1" => "element 1 (indeks: pole1)",
"pole2" => "element 2 (indeks: pole2)",
5 => "element 3 (indeks: 5)"
);
# wydrukowanie zawartości zmiennej
echo("
");
print_r($tablica);
echo("
");
?>
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:


Twój kot i jego imię


if($imie_kota == "") {
echo("
");
echo("Podaj imię swojego kota: ");
echo("");
echo("
");
}
elseif ($imie_kota == "Mruczek") {
echo("Mruczek?");
}
elseif ($imie_kota == "Ramzes") {
echo("Ramzes!");
}
else { echo("Twój kot nazywa się... $imie_kota");
}
?>


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("
");
echo("Podaj imię swojego kota: ");
echo("");
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:

blok HTML

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ę




Podaj imię swojego kota:



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 . "" . "\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:

// tu ciało formularza


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>


Wyszukiwarka

Podobne podstrony:
PHP i MySQL Dla kazdego
kurs php
Webcity pl Kurs PHP Continue
PHP i MySQL Wprowadzenie Wydanie II
PHP i MySQL Witryna WWW oparta na bazie danych Wydanie IV
PHP i MySQL Dla kazdego Wydanie II phmdk2
PHP i MySQL Tworzenie aplikacji WWW phmsap
helion php i mysql tworzenie sklepów internetowych
PHP 5 i MySQL Zastosowania e commerce
przykladowe php mysql

więcej podobnych podstron