Kurs Php & Mysql, Informatyka, ● PHP, MySQL, ORACLE


0x08 graphic

0x08 graphic

0x08 graphic

0x08 graphic

Artur Świderek

as@scrypty.pl

2001-12-01

Spis treści

Czym jest PHP?

PHP A SERWER WWW

PHP może być zainstalowany w dwojaki sposób. Pierwszy, najbardziej popularny, to instalacja jako moduł serwera, np. Apache'a. Wówczas skrypt PHP jest wykonywany na prawach użytkownika, który jest właścicielem Apache'a - zwykle nobody. Drugi, rzadziej stosowany sposób to instalacja PHP jako programu CGI. Wówczas skrypty PHP umieszczane są w katalogu ze skryptami CGI (najczęściej jest to katalog cgi-bin). Należy również pamiętać, taki skrypt jest pełnoprawnym programem CGI (Common ateway Interface) i musi mieć odpowiednie uprawnienia (755, czyli -rwxr-xr-x) oraz w pierwszej linii pliku ścieżkę do interpretera języka.

Instalacja

Aby móc testować skrypty musimy mieć zainstalowany serwer www i interpreter PHP. Pliki instalacyjne do obydwu programów można znaleźć na stronie PHP.pl w dziale download. Po ściągnięciu instalujemy Apache'a w domyślnym katalogu, potem w zależności od wersji interpretera PHP rozpakowywujemy go do katalogu c:\php albo instalujemy do tegoż katalogu. Podczas instalacji zaznaczamy wszystkie możliwe rozszerzenia PHP, tj. .php, .php3 i .phtml. Jeżeli miałeś wersję spakowaną to musisz jeszcze zamienić nazwę pliku c:\php\php.ini-dist na c:\php\php.ini. Wyżej wymieniony plik jest plikiem konfiguracyjnym interpretera, jednak do zwykłego korzystania z interpretera nie jest potrzebna specjalna konfiguracji, dlatego nie będziemy nic w nim zmieniać. Po instalacji serwera i interpretera możesz spróbować uruchomić serwer. Powinien albo krótko po uruchomieniu wyłączyć się, albo po uruchomieniu przeglądarki i próbie wejścia na adres http://127.0.0.1/ powinien wyświetlić się błąd "Strony nie znaleziono" albo coś w tym stylu. Aby serwer działał musimy go odpowiednio skonfigurować.

Konfiguracja

Plikiem konfiguracyjnym Apache'a, który będziemy zmieniać jest httpd.conf, znajdujący się w katalogu conf w katalogu gdzie zainstalowano Apache'a (domyślnie c:\Program Files\Apache Group\Apache\). Otwórz go pod Notatnikiem. Wyszukaj w nim linii z ServerName. Zamień ją na ServerName 127.0.0.1 (może być także localhost). Jeżeli przed ServerName występuje znaczek # (haszyk) to usuń go. W ten sposób ustaliliśmy nazwę serwera, przez którą będziemy mogli wywoływać nasze strony i skrypty. Teraz można uruchomić Apache'a i sprawdzić czy działa. Uruchom Apache.exe, potem przeglądarkę i wejdź na strone http://127.0.0.1/. Powinna pojawić się strona powitalna Apache'a (jeżeli masz starszą wersję Apache'a może wyświetlić się spis plików w katalogu htdocs).
Teraz dodamy kilka rozszerzeń indexu. Standardowo po wywołaniu http://127.0.0.1/ wywoływana jest strona http://127.0.0.1/index.html. Jeżeli takowej nie ma pokazuje się spis zawartości katalogu. Dzięki tej linijce, którą za chwilę zamienimy, będzie (jeżeli nie ma index.html) sprawdzało czy istnieją i uruchamiały index.php i index.php3. Znajdź w pliku konfiguracyjnym linijkę DirectoryIndex. Jeżeli występuje przed nią znak # usuń go. Teraz zamień tę linię na DirectoryIndex index.html index.php index.php3. Serwer sprawdza czy index istnieje w kolejności takiej jak zapisane jest to w pliku konfiguracyjnym, czyli u nas to będzie wyglądało tak:

Teraz czas na dodanie trzech linii do pliku httpd.conf (czyli konfiguracyjnego), informujących serwer www o ścieżce dostępu do interpretera PHP i jego rozszerzeniach. Oto te trzy linie:
ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php3 .php3 .php .phtml
Action application/x-httpd-php3 "/php/php.exe"
Można je wkleić w każdym miejscu pliku. Od tej pory można się już bawić w pisanie skryptów i je testować

Używanie

Wszystkie pliki ze stronami i skryptami przechowywane są w katalogu htdocs w katalogu domyślnym Apache'a. Aby uruchomić skrypt musisz przegrać go do tego katalogu, uruchomić Apache'a i w pasku adresu wpisac http://127.0.0.1/url gdzie url to adres pliku wewnątrz, np.: http://127.0.0.1/katalog/skrypt.php gdzie katalog to folder podrzędny do htdocs (czyli domyślnie adres do tego katalogu to c:\Program Files\Apache Group\Apache\htdocs\katalog), a skrypt.php to nazwa skryptu razem z rozszerzeniem. Jeżeli w katalogu htdocs mamy całą witrynę to możemy ją uruchomić z adresu http://127.0.0.1/katalog, gdzie katalog to folder w którym znajduje się cała witryna. I to wszystko!

ROZSZERZENIA PLIKÓW PHP

Pliki stron WWW zawierających skrypty PHP mogą mieć różne rozszerzenia w zależności od konfiguracji serwera. Najczęściej stosowane to: *.php, *.php3, *.phtml. Jeżeli chcesz, aby pliki PHP miały także inne rozszerzenia, musisz w pliku httpd.conf (lub srm.conf) wpisać w sekcji AddType następującą linię:

AddType application/x-httpd-php .<nowe rozszerzenie>


a następnie, aby plik index z nowym rozszerzeniem był traktowany jako domyślny plik katalogu, w sekcji DirectoryIndex dopisać:

DirectoryIndex index.<nowe rozszerzenie>


UMIESZCZANIE SKRYPTÓW PHP W KODZIE HTML

Skrypty PHP (obecnie Hypertext Preprocessor) wykonywane są po stronie serwera, ale umieszczane bezpośrednio w kodzie strony. Serwer interpretuje kod PHP i przekazuje przeglądarce stronę WWW bez wstawek PHP. Kod PHP umieszczany jest na stronie za pomocą następujących znaczników:

Drugi typ znaczników, nazywany Short Tags (krótkie znaczniki), dostępny jest, jeżli w pliku konfiguracyjnym PHP (c:\apache\php\php.ini w win32) włączona jest opcja short_open_tag:

short_open_tag = On


lub po wywołaniu funkcji short_tags().

Czwarty typ znaczników pochodzi z języka ASP i nie jest dostępny w standardowej konfiguracji PHP. Aby go uaktywnić należy włączyć następującą opcję:

asp_tags = On


PRZYKŁADOWY SKRYPT PHP

W celu przedstawienia podstawowych cech PHP zostanie zaprezentowany i omówiony przykładowy skrypt odpowiedzialny za wyświetlenie na stronie aktualnej daty.

<html>
<head>
<title>Skrypt PHP</title>
</head>
<body>
/* 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
</body>
</html>


Wynikiem działania tego skryptu będzie:

<html>
<head>
<title>Skrypt PHP</title>
</head>
<body>
Dziś jest: 27-07-2001
</body>
</html>


Zwrócony tekst zastąpi znaczniki skryptu (<? i ?>) wraz z umieszczonym między nimi kodem i komentarzami.


Najważniejsze elementy języka

W powyższym przykładzie pobieramy do zmiennej aktualną datę. Jak widać w PHP zmiennych nie trzeba deklarować, a one same rozpoczynają się znakiem $.

Zapis date("d-m-Y") oznacza wywołanie funkcji date(), która zwraca aktualną datę w ustalonym formacie (dzień-miesiąc-rok).

Funkcja echo() odpowiedzialna jest za zwracanie tekstu podanego w nawiasie do przeglądarki. Zauważ, że jako argument funkcji został przekazany tekst umieszczony w podwójnych cudzysłowach ("), w którym znajduje się zmienna $aktualna_data. Ten rodzaj cudzysłowu mówi parserowi PHP, że ma przeszukać tekst w poszukiwaniu zmiennych (rozpoczynających się od znaku $) i zamienić je na ich wartości. Gdybyś zastosował pojedyncze cudzysłowy ('), zwrócony tekst przybrałby następującą postać:

<html>
<head>
<title>Skrypt PHP</title>
</head>
<body>
Dziś jest: $aktualna_data
</body>
</html>


Widać, że teksty umieszczone w takich cudzysłowach nie sa przeszukiwane w celu znalezienia zmiennych i zostają wydrukowane dokładnie tak, jak zostały zapisane.



Komentarze

W powyższym przykładzie użyto trzech rodzajów komentarzy, które służą do oisywania fragmentów kodu i nie są interpretowane przez parser PHP i wysyłane do przeglądarki.

W PHP dostępne są komentarze w stylu języka C, C++ oraz Unix shell:

Komentarze // i # mogą być używane w oddzielnych liniach kodu:

<?
// drukowanie tekstu
echo("jakiś tekst");
# drukowanie tekstu
echo("jakiś tekst");
?>


oraz bezpośrednio po linii kodu zakończonej średnikiem (;):

<?
echo("jakiś tekst"); // drukowanie tekstu
echo("jakiś tekst"); # drukowanie tekstu
?>





Zasady notacji

Podstawowa notacja języka PHP opiera się na następujących zasadach:

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;
?>



Łańcuchy znaków

Łańcuchy znaków przechowują różnego rodzaju teksty. Są one umieszczane w cudzysłowach pojedynczych (') lub w podwójnych ("). Tylko w tej drugiej sytuacji tekst zostanie przeszukany w celu znalezienia zmiennych. Jeżeli natomiast umieścisz tekst w cudzysłowach pochylonych (`), to zostanie on potraktowany przez parser PHP jako polecenie zewnętrzne, które nalezy wykonać.

<?
# 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'

# pobranie listy plików aktualnego katalogu do zmiennej $lista_plikow
$lista_plikow = `dir`; // windows
$lista_plikow = `ls`; // linux
?>



Znaki specjalne

Znaki specjalne w PHP tworzy się przez dodanie przed danym znakiem backslasha (\). Istnieją dwa typy znaków specjalnych: znaki formatujące i znaki drukowane.

Znaki formatujące to np. znak \n, który oznacza przejście do nowej linii.

<?
#drukownie bez znaków \n
echo("pierwsza linia");
echo("druga linia");
?>

Powyższy kod zwróci do przeglądarki następujący wynik:

Pierwsza liniadruga linia


Natomiast ten:

<?
# 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 <br>. Wprowadzone przejścia do nowej linii będą widoczne natomiast w kodzie źródłowym strony.

Aby osiągnąć przejście do nowej linii i w kodzie strony, i w HTML-u, należy zastosować taki sposób pisania:

<?
# drukowanie z użyciem znaków \n i <br>
echo("pierwsza linia<br>\n");
echo("druga linia<br>\n");
?>


Pozwyższy kod zwróci do przeglądarki następujący tekst:

Pierwsza linia<br>
druga linia<br>


Pewne znaki, na przykład $ czy " pełnią specjalne funkcje. Aby parser PHP traktował taki zapis jak normalny znak, a nie początek zmiennej czy tekstu, należy za każdym razem umieścić prze nim baskslash (\).

<?
# 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 <lokalizacja pliku> on line <numer linii>


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). Łańcuch tekstowy będzie traktowany jako liczba zmiennoprzecinkowa, jeśli zawiera jeden ze znaków: -, e lub E. W innym przypadku łańcuch tekstowy będzie traktowany jako liczba całkowita. PHP spróbuje wyszukać na początku tekstu wartość numeryczną i jeśli jej nie znajdzie, podstawi wartość domyślną czyli zero (0).

<?
$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)

$zmienna = "12.0 linii " + 8.0;
// zmienna jest równa 20.0 (liczba zmiennoprzecinkowa)
?>

Używanie stringów

Większość prac w tworzeniu stron internetowych wymaga użycia stringów, więc ich używanie oraz poprawne wykorzystanie jest bardzo ważne dla programisty PHP. Ten tutorial zacznę prostymi przykładami użycia stringów, aby następnie wejść w bardziej zaawansowane techniki wykorzystywania stringów.

W PHP stringiem jest wszystko pomiędzy cudzysłowami:

'Jestem stringiem w pojedynczym cudzysłowie'

"Jestem stringiem w podwójnym cudzysłowie"


Parser PHP rozróżnia stringi poprzez znajdywanie par cudzysłowów. Więc, wszystkie stringi muszą zaczynać się i kończyć tym samym rodzajem cudzysłowu - pojedynczym lub podwójnym. Dla przykładu to NIE są poprawne stringi w PHP:

"Nie jestem poprawnym stringiem ponieważ mam różne cudzysłowy na poczatku i końcu'

'Ja także nie jestem poprawnym stringiem!"


Tylko jeden typ cudzysłowu jest ważny przy definiowaniu stringa, pojedynczy (') lub podwójny ("). Dla przykładu, jeżeli zaczniemy stringa przy pomocy podwójnego cudzysłowu to zakończenie takiego stringa także musi być przy pomocy podwójnego cudzysłowu, inaczej parser nie uzna go jako stringa. Możesz używać pojedynczych cudzysłowów wewnątrz podwójnego I na odwrót.

Oto przykładowe poprawne stringi w PHP:

$s="Jestem 'stringiem w pojedynczym cudzysłowie' wewnątrz podwójnego cudzysłowu ";

$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 = <<<ENDH
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Feedback form</title>
</head>

<h1 align=center>Feedback form</h1>
ENDH;



Łą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 = '<table>';
$html .= '<tr><td>number</td><td>square</td></tr>';

for($i=0; $i<10; $i++) {
$square = $i * $i;
$html .= '<tr><td>' . $i . '</td><td>' . $square . '</td></tr>';
}
$html .= '</table>';



Używanie zmiennych w stringach:

Więc nie chcesz łączyć ze sobą wielu prostych stringów, PHP umożliwia Ci zastosowanie zmiennych wewnątrz podwójnego cudzysłowia. Więc oba poniższe kody dadzą ten sam rezultat $full_name:

$full_name = $first_name . ' ' . $last_name;
$full_name = \"$first_name $last_name\";


Podwójne i pojedyncze cudzysłowy przy stringach są różnie rozróżniane przez PHP. Podwójne cudzysłowia są interpretowane, podczas gdy pojedyncze są traktowane dokładnie w ten sposób w jaki zostały napisane. Dla przykładu:

$foo = 2;
echo "foo is $foo"; // wyświetli: foo is 2
echo 'foo is $foo'; // wyświetli: foo is $foo
echo "foo is $foo\n"; // wyświetli: foo is 2 (z nową linią)
echo 'foo is $foo '; // wyświetli: foo is $foo


Jak widać nawet backslashe nie są rozróżniane w pojedynczych cudzysłowach, pomijając \\ (wstawia backslash), i \" (wstawia podwójny lub pojedynczy cudzysłów).

Podwójne cudzysłowy powinny być używane gdy chcemy użyć zmiennej w stringu lub użyć specjalnego znaku jak \n (nowa linia).

Pojedyncze cudzysłowy powinny być używane dla wszystkich innych stringów. Skrypt używający pojedynczych cudzysłowów wykonuje się trochę szybciej ponieważ parser PHP używa stringów bezpośrednio. Podwójne cudzysłowy są wolniejsze ponieważ muszą zostać zinterpretowane przez parser.

Odwoływanie się do złożonych kombinacji zmiennych wewnątrz stringów może przynieść niespodziewane rezultaty. Więc poniższe linie zadziałają:

echo "value = $foo";
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 = '<a href="'.$url.'">'.$link.'</a>';
$html = "<a href=\"$url\">$link</a>";


HTML nie obsługuje użycia slashy aby zignorować podwójny cudzysłów. Jest to główny problem podczas tworzenia ukrytych zmiennych w HTMLu oraz stałych. Najlepszym wyjściem w tej sytuacji jest użycie funkcji htmlspecialchars(), która umożliwi nam bez problemów umieszczenie danych w ukrytych polach.

Oto kod HTML dla ukrytej zmiennej, która może zawierać podwójny cudzysłów:

<input type=hidden name=var value="<?php echo htmlspecialchars($var) ?>">



Stringi bez użycia cudzysłowów

Możliwe jest użycie stringów w PHP bez zamykania ich w cudzysłów.

Jeżeli jest to pojedyncze słowo bez znaków interpunkcyjnych to można użyć go gdziekolwiek w kodzie gdzie normalnie używa się stringów w cudzysłowach. Działa to także dla argumentów funkcji, tablic i innych.

Oto kilka przykładów stringów bez cudzysłowów:

echo $a[apple]; // apple jest stringiem bez cudzysłowów
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ądź 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;

# drukowanie zawartości elementów tablic
echo $tablica[0] . "<br>\n" . tablica[1] ."<br>\n" .
$inna_tablica["pole1"] . "<br>\n" . $inna_tablica["pole2"];
?>


Ostatnia linia skryptu zwraca następujący kod:

element pierwszy o indeksie 0<br>
element drugi o indeksie 1<br>
19<br>
38



Klasy

Klasy służą do przechowywania zmiennych i funkcji w jednym obiekcie o określonym identyfikatorze.

<?
class koszyk {
var $jablka;

function dodaj_jablko($ilosc) {
$this->jablka += $ilosc;
}

function podaj_jablka() {
return($this->jablka);
}

}
?>


Powyższy kod tworzy klasę o nazwie 'koszyk'. Można na niej wykonać dwie czynności: dodaj daną ilość jabłek oraz odczytać ile jest ich już w koszyku. Spójrzmy zatem na przykład korzystania z takiej klasy:

<?
# stwórz egzemplarz obiektu
$koszyk_1 = new koszyk;

# dodaj pięć jabłek
$koszyk_1->dodaj_jablko(5);

# dodaj jeszcze ilość jabłek w zależności od wartości zmiennej
$ilosc = 3;
$koszyk_1->dodaj_jablko($ilosc);

# odczytaj ilość jabłek w koszyku
$ile = $koszyk_1->podaj_jablka();
echo("Masz $ile jabłek w koszyku");
?>


Ten kod zwróci ilość jabłek w koszyku, czyli:

Masz 8 jabłek w koszyku

NAZWY ZMIENNYCH

W PHP nazwy zmiennych tworzy się poprzez napisanie znaku dolara ($) oraz nazwy określającej zmienną. Na nazwę zmiennej mogą składać się wszystkie litery i cyfry oraz znaki podkreślenia. Zmienna nie może rozpoczynać się od cyfry, lecz może od znaku podkreślenia (_). W nazwach zmiennych rozróżniana jest wielkość liter, dlatego $a i $A to zupełnie różne zmienne z innymi danymi, a nawet z danymi innego typu.

<?
$a = 5; # poprawna nazwa
$_zmienna = 5; # poprawna nazwa
$9sztuk = 5; # niepoprawna nazwa (cyfra na początku zmiennej)
$sztuk9 = 5; # poprawna nazwa
$zażółć_gęślą_jaźń = 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
$a = 2;
$b = 6;
$c = $a * $b;
echo($c); // zmienna $c ma wartość 12

# dzielenie
$a = 6;
$b = 2;
$c = $a / $b;
echo($c); // zmienna $c ma wartość 3

# reszta z dzielenia
$a = 5;
$b = 2;
$c = $a % $b;
echo($c); // zmienna $c ma wartość 1
?>


Powyższy przykład zwraca:

8
4
12
3
1



Operatory przypisania

Operator

Opis

=

Liczba stojąca po lewej stronie operatora przyjmuje wartość liczby stojącej po prawej stronie operatora

+=

Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą sumą jej samej i liczby stojącej po prawej stronie operatora

-=

Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą różnicą jej samej i liczby stojącej po prawej stronie operatora

*=

Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą iloczynem jej samej i liczby stojącej po prawej stronie operatora

/=

Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą ilorazem jej samej i liczby stojącej po prawej stronie operatora

%=

Liczba stojąca po lewej stronie operatora przyjmuje wartość będącą resztą z dzielenia (modulo) jej samej i liczby stojącej po prawej stronie operatora


Przykład:

<?
$a = 5;
echo($a); // zmienna $a ma wartość 5

$a += 3;
echo($a); // zmienna $a ma wartość 8

$a -= 1;
echo($a); // zmienna $a ma wartość 7

$a *= 4;
echo($a); // zmienna $a ma wartość 28

$a /= 2;
echo($a); // zmienna $a ma wartość 14

$a %= 3;
echo($a); // zmienna $a ma wartość 2
?>


Powyższy przykład zwraca:

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...


ZASIĘG ZMIENNYCH

Tworzone w skryptach PHP zmienne nie są widoczne w funkcjach. Funkcje mają swoje zmienne, które mogą mieć nazwy takie, jak inne zmienne użyte wcześniej przed deklaracją funkcji, ale będą miały swoje wartości i nie będą dostępne w skrypcie.

Jeżeli chcesz, aby zmienna stworzona w skrypcie była widoczna w funkcji musisz użyć instrukcji global.

<?
$zmienna = 5;

function druk() {
echo($zmienna);
}

druk();
?>


Powyższy kod w załozeniu miał wydrukować liczbę 5, ale tego nie robi, ponieważ zmienna $zmienna nie jest zmienna globalną, więc nie jest widoczna dla funkcji druk(). Aby osiągnąć cel, należałoby napisać:

<?
$zmienna = 5;

function druk() {
global $zmienna;
echo($zmienna);
}

druk();
?>


ZMIENNE ZMIENNYCH

Zmienne zmiennych, nazywane czasem zmiennymi symbolicznymi mają nazwy utworzone z wartości innych zmiennych.

<?
$a = "test";
$$a = " zmiennych...";

// utworzenie zmiennej o nazwie 'test' z wartością ' zmiennych...'
echo("$a$test");
?>


Powyższy kod zwraca:

test zmiennych...


Spójrzmy na inny przykład:

<?
$zmienna_test = "Działa!";
$a = "zmienna";
$druk = ${$a."_test"};

// utworzenie zmiennej i przypisanie jej wartości zmiennej $zmienna_test
echo($druk);
?>


Powyższy przykład zwraca zawartość zmiennej :

Działa!


ZMIENNE FORMULARZY


Zmienne formularzy to zmienne utworzone na podstawie wysłanego formularza. Jeżeli formularz zawierał pole tekstowe o nazwie imie_kota i użytkownik wpisał do niego imię Mruczek, to w skrypcie dostępna jest zmienna imie_kota o wartości 'Mruczek'

Oto przykładowy formularz:

<form action=imie_kota.php method=post>
Podaj imię swojego kota: <input type=text name=imie_kota>
<input type=submit value=wyślij>
</form>


I skrypt PHP drukujący podane imię kota:

<?
echo("twoj kot nazywa sie... $imie_kota");
?>


Formularze HTML można wysyłać przy użyciu dwu metod: POST i GET. Przy użyciu metody POST dane wysyłane są na standardowym urządzeniu wejściowym - STDIN. Ta metoda nadaje się do przesyłania większych porcji informacji (np. z pól TEXTAREA). W przypadku użycia metody GET dane z formularza oddzielone za pomocą ?, & oraz = wyyłane są w adresie URL. Dane tak przesłane ą oczywiście dostępne w zmiennych o odpowiednich nazwach, ale są również dostępne w zmiennej $QUERY_STRING w postaci:

Parametr1=wartosc1&Parametr2=wartosc2



STAŁE

W PHP możesz również definiować stałe za pomocą funkcji define(). Wartość stałych jest definiowana raz i nie może być zmieniana. Nazwa stałej jest zwyczajowo pisana wielkimi literami, ale nie jest to konieczne.

<?
define("MOJA_STALA","wartość stałej...");
echo(MOJA_STALA);
?>


Powyższy kod zwraca:

wartość stałej...



ZMIENNE PREDEFINIOWANE

Zmienne predefiniowane są tworzone przez PHP automatycznie i zawierają różne informacje na temat serwera, skryptu itp. Pełną listę tych zmiennych uzyskasz wywołując skrypt:

<?
phpinfo();
?>

Zmienne środowiskowe

Zmienne środowiskowe pozwalają na dowiedzenie się o wielu różnych parametrach pracy serwera czy też klienta. Można z nich odczytać informacje np. o systemie operacyjnym, przeglądarce i adresie IP odwiedzającego, a równierz nazwę serwera WWW i port połączenia.

Czasami chcemy wiedzieć coś więcej na temat osób odwiedzających nasze strony, jednak nawet rozbudowana ankieta nie wystarczy, aby zaspokoić naszą ciekawość. Czasami zdarza się również, że chcemy wiedzieć coś więcej nt. serwera, z którego korzystamy, a nasz administrator jest zbyt zajęty, żeby odpowiadać nam na podstawowe pytania. W obu tych przypadkach przychodzą nam z pomocą zmienne środowiskowe. Zmienne te zawierają specjalne informacje dotyczące konfiguracji serwera WWW czy konfiguracji PHP. Poniżej postaram się przedstawić kilkanaście wg mnie przydatnych zmiennych.


Opisy niektórych zmiennych:

$COMPUTERNAME

Zawiera nazwę komputera, z którego korzysta osoba odwiedzająca naszą stronę

$OS

Zawiera nazwę systemu, z jakiego korzysta osoba odwiedzająca naszą stronę.

$SystemDrive

Zawiera nazwę dysku, na którym zainstalowany jest system

$SystemRoot

Zawiera ścieżkę miejsca zainstalowania systemu

$SERVER_SOFTWARE

Zawiera nazwy oprogramowania serwera WWW

$SERVER_NAME

Zawiera nazwę serwera

$SERVER_PROTOCOL

Zawiera nazwę protokołu serwera

$SERVER_PORT

Zawiera numer portu serwera

$PATH_INFO

Zawiera ścieżkę oraz nazwę uruchomionego skryptu

$PATH_TRANSLATED

Zawiera bezwzględną ścieżkę do uruchomionego skryptu

$SCRIPT_NAME

Zawiera nazwę skryptu

$REMOTE_ADDR

Zawiera IP osoby odwiedzającej stronę

$REMOTE_HOST

Zawiera nazwę hosta osoby odwiedzającej stronę

$HTTP_REFERER

Zawiera URL poprzedniej odwiedzonej strony

$HTTP_USER_AGENT

Zawiera nazwę przeglądarki, z której korzysta osoba oglądająca stronę


Te oraz dużo więcej zmiennych wraz z bardzo przydatnymi informacjami nt. serwera i PHP możecie uzyskać tworząc prosty plik php:

<? phpinfo(); ?>


Po uruchomieniu tego pliku waszym oczom ukaże się masa tabelek zawierających odpowiednią ilość informacji, żeby zaspokoić nawet najbardziej ciekawskich.


Wnioski:

Znając tyle zmiennych możemy z nich skorzystać na różne sposoby. Możemy po prostu zmieścić bardzo prostą informację na stronie, która informowała by z jakiej przeglądarki korzysta użytkownik, jaki jest jego adres IP oraz skąd przybywa:

Używasz przeglądarki Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98)
Twój adres IP to 195.117.166.146
Przybyłeś tutaj ze strony http://php.bajo.pl/artykuly.php?id=2

TABLICE

TABLICE JEDNOWYMIAROWE

Tablice jednowymiarowe mogą przechowywać jedną kolumnę danych. Składają się z nazwy tablicy (poprzedzonej znakiem $) i indeksu podanego w nawiasach kwadratowych ([ i ]).

Tworzenie tablic

Tablice można zainicjować (utworzyć) na dwa sposoby: za pomocą funkcji array() oraz poprzez dopisanie nowego (pierwszego) elementu.

<?

$tablica = array();

?>

Powyższy kod tworzy nową tablicę, ale bez żadnego elementu. Można jednak od razu przy tworzeniu tablicy zadeklarować jej elementy:

<?

$tablica = array("element1","element2","element3");

?>

Powyższy przykład tworzy tablicę z już zadeklarowanymi elementami. Elementy oddziela się od siebie za pomocą przecinka, a łańcuchy znaków umieszcza w cudzysłowach. Natomiast jeżeli wartość liczbowa jest liczbą, nie ma potrzeby umieszczania jej w cudzysłowach:

<?

$tablica = array(1,2,3);

?>

Domyślnie pierwszy element ma indeks o wartości 0 Jeżeli chcesz, żeby tablica zaczynała się od innego indeksu, musisz użyć operatora =>.

<?

$tablica = array(1 => "element1","element2","element3");

?>

W podobny sposób możesz utworzyć tablicę z tylko niektórymi indeksami:

<?

$tablica = array(

1 => "element1",

3 => "element2",

5 => "element3"

);

?>

Powyższy przykład różni się trochę w zapisie od poprzedniego, ponieważ zastosowano w nim przejścia do nowej linii i wcięcia, ale tylko w celu zwiększenia czytelności. Nie wpływa to na naszą tablicę, zapis jest za to o wiele bardziej intuicyjny.

Aby utworzyć tablicę zawierającą indeksy tekstowe możemy również posłużyć się operatorem =>:

<?

$tablica = array(

"pole1" => "element1",

"pole2" => "element2",

"pole3" => "element3"

);

?>

Dodawanie elementów

Dodawanie nowych elementów do tablicy odbywa się poprzez napisanie nazwy tablicy i podanie numeru (indeksu) pozycji, do której chcemy dopisać nową wartość:

<?

# indeks liczbowy

$tablica[0] = "element1";

$tablica[1] = "element2";

$tablica[2] = "element3";

?>

Jeżeli dodajesz nowe pozycje do tablicy, tak jak w powyższym przykładzie, możesz uprościć nieco zapis, nie podając numerów indeksów (pisząc samo []). W takim przypadku PHP samo dodaje nowe elementy, poczynając od indeksu o wartości 0. Kolejne elementy dodawane są zawsze na końcu tablicy:

<?

# tworzenie tablicy z indeksami liczbowymi, które nie są podawane

$tablica[] = "element1";

$tablica[] = "element2";

$tablica[] = "element3";

?>

Możesz rónież dopisywać nowe elementy podając indeksy tekstowe:

<?

# indeks tekstowy

$tablica["jeden"] = "element1";

$tablica["dwa"] = "element2";

$tablica["trzy"] = "element3";

?>

Wyświetlenie danych

Odwoływanie się do tablicy jednowymiarowej wymaga napisania nazwy tablicy oraz podania w nawiasach kwadratowych indeksu elemantu. Indeks może być liczbą całkowitą lub łańcuchem znaków.

<?

# definicja tablicy

$tablica = array("element1","element2","element3");

# drukowanie elementów od 0 do 2

echo($tablica[0]);

echo($tablica[1]);

echo($tablica[2]);

?>

Powyższy przykład zwraca listę elementów tablicy:

element1

element2

element3

W podobny sposób drukuje się zawartość tablic o indeksach tekstowych.

<?

#definicja tablicy

$tablica = array(

"pole1" => "element1",

"pole2" => "element2",

"pole3" => "element3"

);

# drukowanie elementów od 'pole1' do 'pole3'

echo($tablica["pole1"]);

echo($tablica["pole2"]);

echo($tablica["pole3"]);

?>

Prowyższy przykład zwraca listę elementów tablicy:

element1

element2

element3

Spójrzmy jeszcze na taki przykład:

<?

$tablica = array(1,2,3);

echo($tablica);

?>

Co zwróci w typ przypadku funkcja echo()? Ponieważ nie został podany indeks elementu tablicy, PHP zwróci tylko nazwę typu zmiennej:

Array

PHP ma wiele funkcji działań na tablicach - od przeglądania po sortowanie. Wszystkie są szczegółowo omówione w manualu PHP na stronach http://pl.php.net.

Funkcja print_r

Funkcja print_r() jest bardzo wygodna przy debugowaniu skryptu. Drukuje ona zawartość podanej zmiennej z uwzględnieniem jej struktury.

<?

#definicja tablicy trójelementowej

# dwa indeksy tekstowe i jeden liczbowy

$tablica = array(

"pole1" => "element 1 (indeks: pole1)",

"pole2" => "element 2 (indeks: pole2)",

5 => "element 3 (indeks: 5)"

);

# wydrukowanie zawartości zmiennej

echo("<pre>");

print_r($tablica);

echo("</pre>");

?>

Powyższy przykład wydrukowania tablicy przy użyciu funkcji print_r() i znaczników <pre> i </pre> (dla zachowania czytelności kodu w przeglądarce) zwraca:

Array

(

[pole1] => element 1 (indeks: pole1)

[pole2] => element 2 (indeks: pole2)

[5] => element 3 (indeks: 5)

)

TABLICE WIELOWYMIAROWE

Tablice wielowymiarowe mogą przechowywać więcej niż jeden rząd danych. Za pomocą takiej tablicy możesz opisać tabelkę składającą się z kolumn i rzędów:

<?
# 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
)

)

Można uczynić deklarację takiej tablicy bardziej czytelną, nazywając indeksy rzędów za pomocą liter A, B, i C:

<?
# rząd pierwszy (A)
$tablica[A][0] = "pole A1";
$tablica[A][1] = "pole A2";
$tablica[A][2] = "pole A3";

# rząd drugi (B)
$tablica[B][0] = "pole B1";
$tablica[B][1] = "pole B2";
$tablica[B][2] = "pole B3";

# rząd trzeci (C)
$tablica[C][0] = "pole C1";
$tablica[C][1] = "pole C2";
$tablica[C][2] = "pole C3";
?>


Struktura takiej tablicy wygląda podobnie, ale rzędy nazywane są odpowiednio A, B i C:

Array
(
[A] => Array
(
[0] => pole A1
[1] => pole A2
[2] => pole A3
)

[B] => Array
(
[0] => pole B1
[1] => pole B2
[2] => pole B3
)

[C] => Array
(
[0] => pole C1
[1] => pole C2
[2] => pole C3
)

)


Jak widać na powyższym przykładzie w PHP można w tablicach wielowymiarowych używać zamiennie indeksów liczbowych i tekstowych. Takie podejście znacznie poprawia czytelność kodu.

Można również tworzyć tablice o większej liczbie wymiarów:

<?
$tablica[A][0][I] = "pole A1 I";
$tablica[A][0][II] = "pole A1 II";
$tablica[A][1][I] = "pole A2 I";
$tablica[A][1][II] = "pole A2 II";

$tablica[B][0][I] = "pole b1 I";
$tablica[B][0][II] = "pole B1 II";
$tablica[B][1][I] = "pole B2 I";
$tablica[B][1][II] = "pole B2 II";
?>


Struktura przykładowej trójwymiarowej tablicy wygląda następująco:

Array
(
[A] => Array
(
[0] => Array
(
[I] = > Pole A1 I
[II] = > Pole A1 II
)

[1] => Array
(
[I] = > Pole A1 I
[II] = > Pole A1 II
)
)

[B] => Array
(
[0] => Array
(
[I] = > Pole B1 I
[II] = > Pole B1 II
)

[1] => Array
(
[I] = > Pole B1 I
[II] = > Pole B1 II
)
)

)




INSTRUKCJE WARUNKOWE

INSTRUKCJA IF

Instrukcja if wykonuje podany kod, jeżeli warunek umieszczony w nawiasach jest prawdziwy (zwraca wartość true). Podstawowa składnia warunku if wygląda następująco:

<?
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:

<form action=imie_kota.php method=post>
Podaj imię swojego kota: <input type=text name=imie_kota>
<input type=submit value=wyślij>
</form>


Spróbujmy teraz napisać skrypt, który będzie drukował powyższy formularz, jeżeli nie podano imienia kota (lub przy wywoływaniu skryptu, jeśli zmienna jest pusta). Najpierw zbudujmy strukturę poprawnej stront HTML zawierającej formularz:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<form action=imie_kota.php method=post>
Podaj imię swojego kota: <input type=text name=imie_kota>
<input type=submit value=wyślij>
</form>

</body>
</html>


Czas teraz na dopisanie instrukcji if, która sprawdzi, czy imie kota zostało podane i czy trzeba wydrukować formularz. Posłużmy się tutaj warunkiem $imie_kota == "":

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
if($imie_kota == "") {
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
}
?>

</body>
</html>


Powyższy przykład drukuje formularz w przypadku, kiedy imię kota nie zostało podane. Ale jak wydrukować stronę z informacją już po wysłaniu formularza? Można to zrobić w taki oto, trochę niezręczny sposób:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
# nie podano imienia
if($imie_kota == "") {
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
}

# podano imię
if($imie_kota != "") {
echo("Twój kot nazywa się... $imie_kota");
}
?>

</body>
</html>



Klauzula else i elseif

Klauzula else oznacza "wykonaj, jeżeli warunek nie był wykonany". To właśnie jej brakowało w poprzednim przykładzie:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
if($imie_kota == "") {
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
}
else
{
echo("Twój kot nazywa się... $imie_kota");
}
?>

</body>
</html>


Klauzula elseif oznacza natomiast "wykonaj, jeżeli warunek nie był spełniony, oraz jeżeli...". Można w ten sposób sprawdzać podane imię kota i wykonywać różne czynności dla różnych imion:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
if($imie_kota == "") {
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
}
elseif ($imie_kota == "Mruczek") {
echo("Mruczek?");
}
elseif ($imie_kota == "Ramzes") {
echo("Ramzes!");
}
else { echo("Twój kot nazywa się... $imie_kota");
}
?>

</body>
</html>


Powyższy przykład jest już znacznie bardziej rozbudowany. Potrafi różnie reagować na podane imiona. Taki sam efekt możesz osiągnąć stosując po klauzuli else instrukcję if:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
if($imie_kota == "") {
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
}
else if ($imie_kota == "Mruczek") {
echo("Mruczek?");
}
else if ($imie_kota == "Ramzes") {
echo("Ramzes!");
}
else { echo("Twój kot nazywa się... $imie_kota");
}
?>

</body>
</html>


Zastosowany sposób zapisu jest różny przywarunkach drugim i trzecim, ale nie wpływa to na ich działanie.


Alternatywny sposób zapisu

PHP udostępnia jeszcze jeden sposób zapisu bloków w warunkach:

<? if (warunek): ?>
blok HTML
<? endif; ?>


Blok rozpoczyna się znakiem :, a kończy instrukcją endif.

Taki sposób zapisu może bardzo ułatwić drukowanie kodu HTML, ponieważ bez używania instrukcji echo() można go umieścić między warunkami:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<? if($imie_kota == ""): ?>
<form action=imie_kota.php method=post>
Podaj imię swojego kota: <input type=text name=imie_kota>
<input type=submit value=wyślij>
</form>
<? elseif ($imie_kota == "Mruczek"): ?>
Mruczek?
<? elseif ($imie_kota == "Ramzes"): ?>
Ramzes!
<? else: ?>
Twój kot nazywa się inaczej niż Mruczek i Ramzes :((
<? endif; ?>

</body>
</html>


Można również zapisać powyższy kod w taki sposób:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
if($imie_kota == ""):
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
elseif ($imie_kota == "Mruczek"):
echo("Mruczek?");
elseif ($imie_kota == "Ramzes"):
echo("Ramzes!");
else:
echo("Twój kot nazywa się... $imie_kota");
endif;
?>

</body>
</html>



OPERATORY DLA WARUNKÓW

W konstruowaniu warunków przydają się bardzo operatory porówania i logiczne:


Operatory porównania

== równość
=== identyczność
!= nierówność
< mniejsze
> większe
<= mniejsze lub równe
>= większe lub równe

<?
# równość
$a = "Mruczek";
if($a == "Mruczek")
echo("Mruczek...");

# identyczność (ta sama wartość i typ zmiennej)
# warunek nie jest spełniony (string i integer)
$a = 0;
if($a === "0")
echo("Identyczne!");

# nierówność
$a = "Ramzes";
if($a != "Mruczek")
echo("Mruczek nie... to może Ramzes");

# mniejsze
$a = 5;
if($a < 0)
echo("Mniejsze od zera");

# większe
$a = 5;
if($a > 0)
echo("Większe od zera");

# mniejsze lub równe
$a = 5;
if($a <= 5)
echo("Mniejsze lub równe 5");

# większe lub równe
$a = 7;
if($a >= 5)
echo("Większe lub równe 5");

?>



Operatory logiczne

and, && równość
or, || identyczność
! nierówność

<?
# and i &&
$a = "Mruczek";
if(($a == "Mruczek") and ($a != "Ramzes"))
echo("Mruczek, ale nie Ramzes")

if(($a == "Mruczek") && ($a != "Ramzes"))
echo("Mruczek, ale nie Ramzes")


# or i ||
$a = "Mruczek";
if(($a == "Mruczek") or ($a == "Ramzes"))
echo("Mruczek lub Ramzes")

if(($a == "Mruczek") or ($a == "Ramzes"))
echo("Mruczek lub Ramzes")


# not
$a = "Mruczek";
if(!($a == "Ramzes"))
echo("Nie Mruczek...");

?>


Jak widać, kolejne warunki umieszcza się w nawiasach okrągłych i łączy za pomocą operatorów logicznych.


INSTRUKCJA SWITCH

Instrukcja switch może zastąpić w naszym przykładzie z imieniem kota blok instrukcji if-elseif-else:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
switch($imie_kota) {
case(""):
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
break;

case("Mruczek"):
echo("Mruczek?");
break;

case("Ramzes"):
echo("Ramzes!");
break;

default:
echo("Twój kot nazywa się... $imie_kota");
}
?>

</body>
</html>


Po każdym bloku występuje instrukcja break, która mówi PHP, że ma przerwać sprawdzanie warunków po wykonaniu powyższych linii kodu (które zostaną wykonane tylko wtedy, gdy zawartość zmiennej podanej w switch() odpowiada wartości podanej w klauzuli case). Gdyby instrukcja break nie została podana, PHP po znalezieniu prawdziwej wartości wykonałoby resztę kodu, nie zwracając uwagi na wartości zawarte w case.

Istnieje również instrukcja exit, która w odróżnieniu od break kończy działanie skryptu.

Klauzula default pełni taką samą funkcję jak else w instrukcji if, oznacza inną wartość, nie podaną wcześniej. Klauzula ta nie musi być podawana zawsze, podobnie jak if w instrukcji warunkowej.



Alternatywny sposób zapisu

Instrukcja switch może być również zapisana w następujący sposób:

<html>
<head>
<title>Twój kot i jego imię</title>
</head>
<body>

<?
switch($imie_kota):
case(""):
echo("<form action=imie_kota.php method=post>");
echo("Podaj imię swojego kota: <input type=text name=imie_kota>");
echo("<input type=submit value=wyślij>");
echo("</form>");
break;

case("Mruczek"):
echo("Mruczek?");
break;

case("Ramzes"):
echo("Ramzes!");
break;

default:
echo("Twój kot nazywa się... $imie_kota");
endswitch;
?>

</body>
</html>


Blok instrukcji switch zostaje w tym przypadku otwarty za pomocą znaku :, a zakończony instrukcją endswitch.



PĘTLE

INSTRUKCJA WHILE

Podstawowa struktura pętli while przedstawia się następująco:

<?
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.


INSTRUKCJA DO..WHILE

Podstawowa struktura pętli do..while przedstawia się następująco:

<?
do {
# kod pętli
} while (warunek);
?>


Pętla do..while jest wykonywana aż do momentu, gdy warunek przyjmie wartość false. Natomiast nawet jeżeli warunek od początku nie był prawdziwy, pętla zostanie wykonana jeden raz. Spójrzmy na taki przykład:

<?
$i = 1;
do {
echo "Licznik ma wartość: " . $i++ ."\n";
} while ($i <= 5);
?>


Pętla zostanie wykonana 5 razy. Na początku zmienna ma wartość b>1. Linia zostaje wydrukowana i następuje inkrementacja zmiennej. Jeżeli warunek nadal jest prawdziwy, sytuacja się powtarza. Przykład ten zwróci:

Licznik ma wartość: 1
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;
do {
echo "Licznik ma wartość: " . $i++ ."\n";
} while ($i <= 5);
?>


Jeśli użyliśmy pętli while, kod niczego nie zwracał, ale w tym przykładzie otrzymamy następujący wynik:

Licznik ma wartość: 6


Zostaje wydrukowana jedna linia, ponieważ sprawdzanie warunku wykonania pętli następuje dopiero po wykonaniu instrukcji. PHP wykonuje kod jeden raz i dopiero potem sprawdza warunek.



INSTRUKCJA FOR

Podstawowa struktura pętli for przedstawia się następująco:

<?
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 speŁniony warunek i jeżeli jest on spełniony, następuje wykonanie pętli. Jeżeli warunek zwróci wartość false, pętla zostaje przerwana. Wyrażenie inkrementacja lub dekrementacja służy do zwiększania lub zmniejszania wartości licznika. Pętla for oferuje podobne możliwości jak pętla while.

Spójrzmy na przykład zastosowania pętli for:

<?
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
?>

<?
foreach ($tablica as $key => $value)
# kod pętli
?>


Ta konstrukcja pozwala na łatwe przeglądanie tablic. Jeśli w kodzie znajduje się więcej niż jedna linia, umieszcza się go w nawiasach klamrowych jako blok instrukcji. Spójrzmy na przykład:

<?
$tablica = array(
1 => "element1",
3 => "element2",
5 => "element3"
);

echo("Zawartość tablicy: ");

foreach ($tablica as $value) {
echo($value);
}
?>


Powyższy przykład zwraca:

Zawartość tablicy:
element1
element2
element3


Możliwe jest również wydrukowanie liczbowego bądź tekstowego indeksu danego elementu. Do tego celu wykorzystamy operator => przy deklaracji pętli:

<?
$tablica = array(
"pole1" => "element1",
"pole2" => "element2",
"pole3" => "element3"
);

echo("Zawartość tablicy: ");

foreach ($tablica as $key =>$value) {
echo "\$tablica[$key] = " . $value . "\n";
}
?>


Powyższy kod podaje już indeksy drukowanego elementu:

Zawartość tablicy:
$tablica[pole1] = element1
$tablica[pole2] = element2
$tablica[pole3] = element3



Alternatywny sposób zapisu

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


TWORZENIE FUNKCJI

W PHP funkcje deklaruje się za pomocą słowa kluczowego function. Następnie podaje się, po spacji oddzielającej nazwę funkcji oraz w nawiasach okrągłych zmienne argumentów. Kod instrukcji funkcji umieszcza się wewnątrz bloku wyznaczonego przez nawiasy klamrowe:

<?
function test($argument_1, $argument_2, $argument_n) {
# kod funkcji
# i inne instrukcje
}
?>



ARGUMENTY FUNKCJI

Aby funkcja mogła operować na konkretnych danych, trzeba je jakoś do niej przekazać. Właśnie do tego służą argumenty. Przy deklarowaniu funkcji jest to lista zmiennych oddzielonych przecinkami. Przy wywołaniu funkcji podaje się natomiast listę wartości, również oddzielonych przecinkami. PHP wspiera przekazywanie argumentów przez wartość i przez referencje. Dostępne są równiez domyślne wartości argumentów i zmienne liczba argumentów.


Przekazywanie argumentów przez wartość

Typowym sposobem przekazywania argumentów jest ich przekazywanie przez wartość. Spójrzmy na przykład:

<?
function test(argument_1,argument_2){
echo("Podano następujące argumenty\n $argument_1\n $argument_2");
}
?>


Wywołanie tej funkcji wygląda następująco:

<?
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";
test(10);
?>


Powyższe wywołania funkcji test() zwracają:

Podano następujące argumenty: jeden
dwa

Podano następujące argumenty:
10
<nie_podano>


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 = "<nie_podano>", $argument_1) {
echo("Podano następujące argumenty:\n $argument_1\n $argument_2");
}
?>


Oto różne wywołania tej funkcji:

<?
test("jeden", "dwa");
echo "\n\n";
test(10);
?>


Powyższe wywołania funkcji test() zwracają:

Podano następujące argumenty:
dwa
jeden

<br>
Warning: Missing argument 2 for test() in <lokalizacja pliku> on line <numer linii>
Podano następujące argumenty:


Zwrócone ostrzeżenie świadczy o niepodaniu wymaganego argumentu wywołania funkcji.

Przy tego typu deklaracjach argumentów bardzo przydają się funkcje func_num_args(), func_get_arg() oraz func_get_args().



func_num_args()

Funkcja ta zwraca liczbę podanych argumentów wywołania funkcji:

<?
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.


Przekazywanie argumentów przez wartość

Typowym sposobem przekazywania argumentów jest ich przekazywanie przez wartość. Spójrzmy na przykład:

<?
function test(argument_1,argument_2){
echo("Podano następujące argumenty\n $argument_1\n $argument_2");
}
?>


Wywołanie tej funkcji wygląda następująco:

<?
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";
test(10);
?>


Powyższe wywołania funkcji test() zwracają:

Podano następujące argumenty: jeden
dwa

Podano następujące argumenty:
10
<nie_podano>


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 = "<nie_podano>", $argument_1) {
echo("Podano następujące argumenty:\n $argument_1\n $argument_2");
}
?>


Oto różne wywołania tej funkcji:

<?
test("jeden", "dwa");
echo "\n\n";
test(10);
?>


Powyższe wywołania funkcji test() zwracają:

Podano następujące argumenty:
dwa
jeden

<br>
Warning: Missing argument 2 for test() in <lokalizacja pliku> on line <numer linii>
Podano następujące argumenty:


Zwrócone ostrzeżenie świadczy o niepodaniu wymaganego argumentu wywołania funkcji.

Przy tego typu deklaracjach argumentów bardzo przydają się funkcje func_num_args(), func_get_arg() oraz func_get_args().

func_num_args()

Funkcja ta zwraca liczbę podanych argumentów wywołania funkcji:

<?
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ęć



PRZYKŁAD FUNKCJI

Napiszemy teraz funkcję, która będzie potrafiła podany tekst umieścić w znacznikach pogrubienia (<b> i </b>), podkreślenia (<u> i </u>), czy pochylenia (<i> i </i>), wykorzystując do tego celu wartości domyślne i instrukcję switch:

<?

function html($text, $type = "bold") {

switch($type) {

case "bold":

$zn = "b";

break;

case "underline":

$zn = "u";

break;

case "italic":

$zn = "i";

break;

}

$new_text = "<$zn>" . $text . "</$zn>" . "\n";

echo $new_text;

}

?>

Spójrzmy na przykład wywołania tej funkcji:

<?

html("To jest pogrubiony tekst...");

html("To jest pogrubiony tekst...", "bold");

html("To jest podkreślony tekst...", "underline");

html("To jest pochylony tekst...", "italic");

?>

Powyższe wywołania funkcji html() zwracają:

<b>To jest pogrubiony tekst...</b>

<b>To jest pogrubiony tekst...</b>

<u>To jest podkreślony tekst...</u>

<i>To jest pochylony tekst...</i>

KLASY


Klasy służą do przechowywania zmiennych i funkcji w jednym obiekcie o określonym identyfikatorze. Zostało już częściowo omówione w rozdziale zmienne.


TWORZENIE KLAS

Klasy tworzy się za pomocą słowa kluczowego class:

<?
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, jakie otrzymuje i nie ma sposobu na ich połączenie, nawet jeżeli żądania te są zapisywane. Jeżeli siądę przed swoim komputerem w Chicago a ty przy swoim, i oboje załadujemy kolejno pierwszą i drugą stronę z witryny hotelu na Karaibach, protokół HTTP nie zaoferuje żadnej pomocy przy rozpoznaniu, że tych dwoje ludzi oglądało dwie kolejne strony. Od strony serwera były to cztery żądania załadowania stron z dodatkowymi danymi związanymi z każdym wywołaniem. Nie tylko taka informacja nie identyfikuje cię (za pomocą nazwiska, adresu e-mail, numeru telefonu lub innego identyfikatora), ale również nie oferuje nic, co może zidetyfikować żądania kolejnych stron jako pochodzące od jednej osoby.


Dlaczego się tym zajmujemy?

Jeżeli twoja witryna jest przeznaczona tylko do dostarczania rozmaitych stron różnym użytkownikom, to w zasadzie nie musisz wiedzieć, kiedy sesja się rozpoczyna, a kiedy kończy. Jednak istnieje wiele sytuacji, kiedy chcemy to wiedzieć.

Dla wszystkich zastosowań powinniśmy skorelować żądania załadowania stron z kolejnymi częściami sesji; dla niektórych zastosowań wygodnie byłoby zapamiętywać niektóre dane w połączeniu z sesją. Sesje PHP rozwiązują oba te problemy.


Alternatywy sesji:

Zanim zajmiemy się podejściem PHP do sesji, wymieńmy kilka alternatywnych sposobów rozwiązania problemu. Jak się później przekonamy, podejście PHP stanowi kombinację kilku z tych technik:


1. Adres IP

Serwery WWW znają albo nazwę, albo adres IP komputera, z którego przyszło żądanie załadowania strony. W większości konfiguracji PHP są one dostępne w zmiennych, odpowiednio $REMOTE_HOST i $REMOTE_NAME. Wydaje się, że identyfikacja komputera jest jednoznaczna z użytkownikiem, co najmniej w krótkim czasie. Jeżeli w krótkim okresie dostaniesz dwa żądania z tego samego adresu IP, kod może stwierdzić, że zostały one wysłane przez tę samą osobę, która przeszła z jednej strony witryny na drugą.

Niestety adres IP twojej przeglądarki nie musi pasować do komputera, z którego korzysta użytkownik. Zarówno AOL, jak i inni dostawcy internetu często stosują serwery proxy, które działają jako pośrednicy. Jeżeli przeglądarka zażąda załadowania URL, wysyła on to żądanie do docelowego serwera i zwraca stronę użytkownikowi. Taka konfiguracja powoduje, że wielu użytkowników może jednocześnie przeglądać twoją witrynę pozornie z jednego adresu IP. Adresy IP nie są więc wystarczająco jednoznaczne, aby stanowiś podstawę do śledzenia sesji.


2. Ukryte zmienne

Każde wywołanie HTTP jest obsługiwane niezależnie, ale za każdym razem gdy użytkownik przejdzie do innej strony witryny, jest zwykle realizowane przez łącze lub przetworzenie formularza. Jeżeli pierwsza strona, którą użytkownik odwiedza, może wygenerować identyfikator tej wizyty, a następne przejścia ze strony do strony mogą go przenosić.

Poniższy przykładowy fragment kodu można zamieścić na początku strony:

if(!isset($session_id))
$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:

<a href=next.php?session_id=$session_id>Następna strona</a>


Każdy formularz powinien zawierać ukryty argument POST:

<form action=next.php method=post>

// tu ciało formularza

<input type=hidden name=session_id value=$session_id>

</form>


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<br>");


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<br>");
session_register('city');
echo("$city<br>");
$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.

Efektem rejestracji jest zapamiętanie przypisań do obiektów (po zakończeniu skryptu zarejestrowane zmienne podlegają serializacji i są przenoszone w sposób, który zapewnia ich odtworzenie w wywołaniu session_start())

Jeżeli nie wywołano wcześniej funkcji session_start(), session_register niejawnie ją wywołuje.

session_unregister()

Wymaga ciągu jako argumentu i usuwa z listy zarejestrowanych zmiennych zmienną o nazwie przekazanej jako argument. W wyniku tego zmienna ta nie będzie podlegała serializacji i nie będzie przenoszona pomiędzy stronami (nazwa zmiennej nie powinna zawierać początkowego znaku '$'.

session_is_registered()

Sprawdza, czy zmienna o podanej nazwie jest zarejestrowana w bieżącej sesji, zwracając TRUE, jeżeli zmienna jest zarejestrowana, FALSE, jeżeli nie jest.

session_destroy()

Wywołanie tej funkcji usuwa wszystkie zapamiętane dane o sesji (identyfikator sesji nie musi się zmieniać po wywołaniu tej funkcji). Wywołanie tej funkcji nie zmienia wartości żadnych zmiennych w bieżącym sktypcie.

session_name()

Funkcja wywołana bez parametrów zwraca nazwę bieżącej sesji. Jest to zwykle 'PHPSESSID'.

Wywołana z jedym argumentem session_name() ustawia nazwę bieżącej sesji na podany ciąg. Nazwa ta jest używana jako klucz do odszukania identyfikatora sesji w cookie lub argumentach GET, POST. Aby odnalezienie sesji się udało, nazwa sesji musi być identyczna jak nazwa sesji, w trakcie której poddano zmienne serializacji. Zauważ, że nie ma powodu do zmiany nazwy sesji, chyba, że chcesz rozróżniać różne typy sesji obsługiwanych jednocześnie przez serwer WWW (np. w przypadku wielu witryn korzystających z sesji). Nazwa sesji jest zmienna na domyślną za każdym uruchomieniem skryptu, więc zmiana nazwy sesji musi zostać wykonana w każdym skrypcie przez wywołaniem innej funkcji obsługi sesji.

session_module_name()

Jeżeli nie zostaną podane żadne argumenty, funkcja zwraca nazwę modułu odpowiedzialnego za obsługę danych sesji. Nazwa ta jest domyślnie ustawiona na 'files', co oznacza, że dane sesji po serializacji są zapisywane do plików w katalogu ustawionym przez funkcję session_save_path(). Jeżeli podany zostanie ciąg jako argument, nazwa modułu jest zmienna na ten ciąg (np. 'user' dla zdefiniowanej przez użytkownika bazy danych sesji; ale nie powinieneś zmieniać tego parametru, jeżeli nie wiesz dokładnie co robisz).

session_save_path()

Zwraca (lub ustawia w przypadku podania argumentu) ścieżkę do katalogu, w którym zapisywane są wartości zmiennych sesji (zwykle jest to /tmp w systemach Unix). Katalog ten musi mieć odpowiednio ustawione uprawniwnia, aby PHP mógł tam zapisywać pliki.

session_id()

Nie ma argumentów. Zwraca ciąg, który jest kluczem, określającym sesje. Jeżeli zostanie przekazany argument, funkcja ta ustawi identyfikator sesji na tę wartość.

session_encode()

Zwraca ciąg z zakodowanym stanem bieżącej sesji, który może zostać zdekodowany przez funkcję session_decode(). Ciąg ten może zostać użyty do zapamiętania sesji w celu odtworzenia jej za jakiś czas (np. zapisanie zakodowanego ciągu w pliku lub w bazie danych).

session_decode()

Pobiera wynik działania funkcji session_encode() i odtwarza stan sesji, zmieniając zmienne sesji na zmienne strony (analogicznie do session_start()).




Podsumowanie

Sesje są użyteczne w sytuacjach, gdy chcesz śledzić działania użytkownika w przypadku interakcji trwającej dłużej niż wykonanie jednego skryptu. Jeżeli prezentowana zawartość strony zależy od działań podejmowanych na poprzedniej, kod powinien zapamiętywać i przenosić te informacje w sposób, który umożliwia odróżnienie poszczególnych użytkowników. Ponieważ protokół HTTP jest protokołem bezstanowym, prowadzi to do zastosowania technik zastępczych - zwykle albo ukrytych zmiennych (które są niestety kłopotliwe), albo cookies (niektóre przeglądarki klientów ich nie obsługują).

Implementacja sesji w PHP hermetyzuje te skomplikowane zagadnienia. Identyfikatory sesji są tworzone i rozprowadzone w sposób automatyczny, a mechanizm rejestracji pozwala programiście dołączać dowolne dane PHP do sesji. Poza początkowym dołączeniem się do sesji i zarejestrowaniem zmiennych, które powinny zostać rozpropagowane poza bieżącą stronę, użycie sesji jest dla programisty przejrzyste.


Grafika w PHP

Programowanie w PHP nie kończy sie na operacjach na plikach i korzystania z bazy danych. Można dzięki niemu tworzyć grafikę i zapisywać ją do plików lub wyświetlać na stronie. Ten artykuł ma ci pomóc w tworzeniu obrazków w PHP.

Co będzie potrzebne?

Aby tworzyć grafikę za pomocą PHP musisz mieć zainstalowaną bibliotekę GD zintegrowaną z twoim interpreterem PHP. Aktualnie biblioteka GD jest dodawana do każdej wersji PHP. W wersji 4.0.6 biblioteka ta znajduje się w katalogu extensions i nazywa się php_gd.dll. Aby uruchomić tę bibliotekę w interpreterze PHP należy w pliku php.ini zmienić linijkę extension_dir = ./ na extension_dir = ./extensions oraz ;extension=php_gd.dll na extension=php_gd.dll. Teraz zapisz plik i jeżeli chodzi o instalację to wszystko!

Programowanie

Najnowsza biblioteka GD obsługuje tylko formaty PNG i JPEG. Funkcje obsługujące te formaty nazywają się tak samo z wyjątkiem dwóch: imagePNG()/imageJPEG() i imagecreatefromPNG()/imagecreatefromJPEG(). Jednak przed użyciem w skrypcie jakichkolwiek funkcji graficznych należy poinformować interpreter i przeglądarkę, że przesyłane dane to grafika. Robimy to za pomocą funkcji Header(), np.:

Header("Content-type: image/png");

Header("Content-type: image/jpeg");

Pierwsza funkcja instruuje interpreter, że przesyłane dane to plik graficzny w formacie PNG, a druga, że w formacie JPEG.

Gdy już poinformowaliśmy przeglądarkę, że skrypt tworzy grafikę, powinniśmy utworzyć nowy rysunek. Służy do tego funkcja imagecreate(), posiadająca dwa parametry - szerokość i wysokość obrazka. Przykład użycia tej funkcji:

$rysunek = imagecreate(200, 200);

W ten oto sposób stworzyliśmy obrazek w kształcie kwadratu o wymiaracha 200x200. Zmienna $rysunek to uchwyt do tego właśnie rysunku. Uchwyt ten będzie potrzebny przy wszystkich operacjach na rysunku.

Kolejną podstawową funkcją w programowaniu grafiki w PHP jest imagePNG() bądź też imageJPEG(), zależnie od formatu. Parametrami tej funkcji są:
- uchwyt obrazka
- nazwa pliku do którego ma być zapisany rysunek - jest to parametr opcjonalny, jeżeli nie wpiszesz jego wartości, interpreter prześle rysunek wprost do przeglądarki, mówiąc prościej - wyświetli go w przeglądarce.
Przykładowe użycia tej funkcji:

imagePNG($rysunek);
imagePNG($rysunek,"rysuj.png");
imageJPEG($rysunek);
imageJPEG($rysunek,"rysuj.jpg");

W pierwszym przykładzie wyświetlamy rysunek w formacie PNG. W drugim tworzymy plik z rysunkiem o nazwie rysuj.png w formacie PNG. Następny wyświetla rysunek w formacie JPEG. No i ostatni zapisuje rysunek do pliku o nazwie rysuj.jpg w formacie JPEG.

Ostatnią ważną funkcją, którą powinniśmy stosować na końcu każdego skryptu tworzącego grafikę jest imagedestroy(). Jedynym parametrem tej funkcji jest uchwyt obrazka. Funkcja ta usuwa z obrazek z pamięci komputera.

Poznaliśmy już wszystkie funkcje inicjujące, teraz powinniśmy zająć się... rysowaniem. Przy rysowaniu należy pamiętać, że obrazek zaczyna się na współrzędnych 0 0, a kończy się na maksymalnej szerokości minus 1 i maksymalnej wysokości minus 1. Tak więc przy obrazku wielkości 10x10, ostatnim widocznym pikselem będzie 9 9.

Spis wszystkich funkcji zajmujących się obróbką obrazu zamieszczam w poniższej tabelce:

imagearc(int $uchwyt, $sx, $sy, $szer, $wys, $pocz_kata, $kon_kata, $kolor)

Tworzy wycinek elipsy o środku $sx $sy o szerokości $szer i wysokości $wys, między kątem $pocz_kata a $kon_kata w kolorze równym $kolor.

imagechar(int $uchwyt, $czcionka, $x, $y, string $znak, int $kolor)

Rysuje znak poziomo od punktu $x $y, w danym kolorze. Standardowo w PHP istnieją czcionki od 1-5.

imagecharup(int $uchwyt, $czcionka, $x, $y, string $znak, int $kolor)

Rysuje znak pionowo od punktu $x $y, w danym kolorze.

int imagecolorallocate(int $uchwyt, $red, $green, $blue)

Zwraca uchwyt barwy o podanej zawartości kolorów RGB.

imagecopyresized(int $uchwyt_docelowy, $uchwyt_zrodlowy, $docel_x, $docel_y, $zrodl_x, $zrodl_y, $docel_szer, $docel_wys, $zrodl_szer, $zrodl_wys)

Kopiuje wycinek z obrazka źródłowego o punkcie początkowym $zrodl_x $zrodl_y, szerokości $zrodl_szer i wysokości $zrodl_wys. Następnie wkleja do obrazka docelowego zaczynając od punktu $docel_x $docel_y, zmieniając szerokość wycinka do $docel_szer i wysokość do $docel_wys.

int imagecreatefromJPEG(string $url_obrazka)

Tworzy uchwyt do obrazka w formacie JPEG z pliku o podanym urlu.

int imagecreatefromPNG(string $url_obrazka)

Tworzy uchwyt do obrazka w formacie PNG z pliku o podanym urlu.

imagedashedline(int $uchwyt, $x1, $y1, $x2, $y2, $kolor)

Rysuje przerywaną linię z punktu $x1 $y1 do punktu $x2 $y2 w podanym kolorze.

imagefill(int $uchwyt, $x, $y, $kolor)

Zalewa obrazek kolorem z punktu $x $y do pierwszej napotkanej linii tego samego koloru.

imagefilledpolygon(int $uchwyt, array $tablica_punktow, int $ilosc_punktow, $kolor)

Rysuje wypełniony kolorem wielokąt. Współrzędne wszystkich punktów są zawarte w tablicy punktów, w której indeksy parzyste to współrzędne x wierzchołków wielokąta, a nieparzyste to współrzędne y wierzchołków wielokąta.

imagefilledrectangle(int $uchwyt, $x1, $y1, $x2, $y2, $kolor)

Rysuje wypełniony kolorem prostokąt, którego lewy-górny wierchołek ma współrzędne $x1 $y1, a prawy-dolny $x2 $y2.

imagefilltoborder(int $uchwyt, $x, $y, $kol_graniczny, $kolor)

Wypełnia rysunek kolorem od punktu $x $y do linii o podanym kolorze - $kol_graniczny.

int imagefontheight(int $czcionka)

Zwraca wysokość czcionki w pikselach.

int imagefontwidth(int $czcionka)

Zwraca szerokość czcionki w pikselach.

imageinterlace(int $uchwyt, $przeplot)

Włącza ($przeplot=1) lub wyłącza ($przeplot=0) przeplot.

imageline(int $uchwyt, $x1, $y1, $x2, $y2, $kolor)

Rysuje prostą z punktu $x1 $y1 do punktu $x2 $y2 w podanym kolorze.

int imageloadfont(string $plik)

Ładuje nową czcionkę. Plik z definicją czcionki powinien być wygenerowany na komputerze z takim samym procesorem, w jaki został wyposażony komputer z interpreterem PHP.

imagepolygon(int $uchwyt, array $punkty, int $il_punktow, $kolor)

Rysuje wielokąt, którego współrzędne wierzchołków są zapisane w formie tablicy, gdzie indeksy parzyste to współrzędne x, a indeksy nieparzyste to współrzędne y, a ilość wierzchołków jest zapisana jako $il_punktow.

imagerectangle(int $uchwyt, $x1, $y1, $x2, $y2, $kolor)

Rysuje prostokąt, którego lewy-górny wierzchołek ma współrzędne $x1 $y1, a prawy-dolny $x2 $y2. Zmienna $kolor przechowuje kolor krawędzi tego prostokąta.

imagesetpixel(int $uchwyt, $x, $y, $kolor)

Rysuje pojedynczy piksel o współrzędnych $x $y w podanym kolorze.

imagestring(int $uchwyt, $czcionka, $x, $y, string $lancuch, int $kolor)

Rysuje łańcuch znaków w podanej czcionce i kolorze, zaczynając od punktu $x $y.

imagestringup(int $uchwyt, $czcionka, $x, $y, string $lancuch, int $kolor)

Rysuje w pionie łańcuch znaków w podanej czcionce i o podanym kolorze, zaczynając od punktu $x $y.

int imagesx(int $uchwyt)

Zwraca szerokość obrazka

int imagesy(int $uchwyt)

Zwraca wysokość obrazka

imagettftext(int $uchwyt, $wielkosc, $kat, $x, $y, $kolor, string $plik, $tekst)

Wyświetla tekst przy użyciu czcionki True Type, znajdującej się w pliku zaczynając od punktu $x $y w podanym kolorze. Jeżeli $kat jest równy 0, to napis jest rysowany w poziomie. Funkcja potrzebuje dodatkowo biblioteki Freetype.

int imagecolorat(int $uchwyt, $x, $y)

Zwraca indeks koloru piksela o współrzędnych $x $y.

int imagecolorclosest(int $uchwyt, $red, $green, $blue)

Zwraca indeks najbliższego koloru.

int imagecolorexact(int $uchwyt, $red, $green, $blue)

Zwraca indeks koloru.

int imagecolorresolve(int $uchwyt, $red, $green, $blue)

Zwraca indeks koloru, jeżeli nie ma takowego w palecie obrazka zwraca najbliższy mu.

bool imagecolorset(int $uchwyt, $indeks, $red, $green, $blue)

Określa kolor podanego indeksu palety

array imagecolorsforindex(int $uchwyt, $indeks)

Zwraca tablicę asocjacyjną kolorów RGB palety o podanym indeksie. Indeksami poszczególnych kolorów są: "red", "green" i "blue".

int imagecolorstotal(int $uchwyt)

Zwraca ilość kolorów zawartych w palecie obrazka

Oto przykładowy skrypt wykorzystujący bibliotekę GD. Ma on generować szachownicę o ilości pól x*x. Dla skrócenia kodu x ustaliłem sam i ma on wartość 100. Można oczywiście stworzyć formularz, który będzie wysyłał zmienną x do tego skryptu.

<?PHP

Header("Content-type: image/png");

$img = imagecreate(200, 200);

$bialy = imagecolorallocate($img, 255, 255, 255);

$czarny = imagecolorallocate($img, 0, 0, 0);

imagefill($img, 0, 0, $bialy);

$x = 100;

$y = round(200/$x);

for($i=0;$i<$x;$i++)

for($j=0;$j<$x;$j++) {

if(($i+$j)%2==0) {

imagefilledrectangle($img,$j*$y,$i*$y,$j*$y+$y,$i*$y+$y,$bialy);

} else

imagefilledrectangle($img,$j*$y,$i*$y,$j*$y+$y,$i*$y+$y,$czarny);

}

imagePNG($img);

imagedestroy($img);

?>

MySQL

CZYM JEST BAZA DANYCH?

Coraz częściej zachodzi potrzeba pobierania i przechowywania danych od użytkownika. Do przechowywania danych najlepiej użyć właśnie baz danych. Czym one są, dowiesz się czytając tą część kursu.

POJĘCIE BAZY DANYCH

Z bazami danych spotkałeś się już pewnie niejeden raz. Bazą danych jest na przykład książka adresowa w Twoim programie pocztowym. Bazy danych używane są w bankach i większych przedsiębiorstwach do przechowywania informacji o kontach czy też danych personalnych.

Przechowywanie danych w bazach odbywa się w określony sposób. Na bazę danych składają się tabele, a w nich rekordy podzielone na pola.

RODZAJE BAZ DANYCH

Bazy danych możemy podzielić na płaskie i relacyjne.


Płaskie bazy danych

Tego typu bazy danych to nic innego jak pliki tekstowe, w których zastosowano odpowiedni klucz podziału na rekordy i pola. Najczęściej rekordy są osobnymi liniami pliku, a pola oddzielone są umownym znakiem, np. średnikiem, dwukropkiem, czy tabulatorem. Trzeba jednak pamiętać o tym, że znak separacji nie może występować w zawartości pól. Można również zdefiniować długość poszczególnych pól; nie ma wtedy potrzeby oddzielania ich, ponieważ wiadomo w którym miejscu zaczyna się odpowiednie pole.

Poniższy przykład prezentuje płaską bazę danych:

1;Noc na ziemi;Jim Jarmush
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 przejdź 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 ISTNIEJĄCYCH BAZ DANYCH

Z pewnością chciałbyś wiedzieć, jakie bazy danych są dostępne, zanim zazcniesz tworzyć nowe, własne bazy. Aby wyświetlić listę dostępnych baz danych posłużmy się poleceniem show databases. Zaloguj się do MySQL-a i wydaj polecenie show databases;:

mysql> show databases;

+----------+

| Database |

+----------+

| mysql |

| test |

+----------+

2 rows in set (0.00 sec)

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.

TWORZENIE NOWEJ BAZY DANYCH

Aby rozpocząć naukę MySQL-a, utwórzmy najpierw naszą pierwszą, przeznaczoną do testów bazę danych. Tworzenie zarówno tabel, jak i baz odbywa się za pomocą polecenia create z odpowiednimi argumentami (w tym przypadku database i nazwą bazy, którą chcemy utworzyć):

mysql> create database nasza_baza;
Query OK, 1 row affected (0.06 sec)

mysql>


Właśnie utworzyliśmy nową bazę danych o nazwie nasza_baza. MySQL poinformował nas o powodzeniu i czasie wykonania polecenia. Spójrzmy zatem na listę dostępnych baz danych:

mysql> show databases;

+------------+

| Database |

+------------+

| mysql |

| test |

| nasza_baza |

+------------+

3 rows in set (0.00 sec)

mysql>


Jak widać pojawiła się tam nowa pozycja, nasza_baza.

USUWANIE BAZY DANYCH

Ponieważ utworzyliśmy własną bazę danych do testów, nie jest już nam potrzebna baza test. Usuńmy ją za pomocą polecenia drop z odpowiednimi argumentami (w tym przypadku databases i nazwą bazy, którą chcemy usunąć):

mysql>drop database test;
Query ok, 0 rows affected (0.00 sec)

mysql>


Sprawdźmy, 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ądź edytowanie) musimy najpierw "powiedzieć" MySQL-owi, nad którą bazą danych mamy zamiar pracować. Można to zrobić na dwa sposoby:

Spójrzmy na przykład z zastosowaniem komenty use:

mysql> use nasza_baza
Database changed

mysql>


WYŚWIETLANIE ISTNIEJĄCYCH TABEL

Kiedy baza została już wybrana (w tym przypadku nasza_baza), możemy przystąpić do wyświetlania tabel. Do tego celu służy poznana wcześniej komenda show z argumentem tables:

mysql> show tables
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 <nazwa_tabeli> oraz definicją listy pól. Wybrane typy pól są przedstawione poniżej.

Typ pola

Opis

CHAR(M)

Pole znakowe. Przechowuje teksty o ustalonej z góry długości. Ograniczone do 255 znaków.

VARCHAR(M)

Pole znakowe. Przechowuje taką długość tekstu, jaka jest używana.

INT[(M)] [UNSIGNED]

Pole liczb całkowitych. Przechowuje liczby z zakresu od -2147483648 do 2147483647 (z parametrem UNSIGNED - od 0 do 4294967295).

DATE

Pole daty przechowuje daty z zakresu od '1000-01-01' do '9999-12-31'.

BLOB/TEXT

Pole tekstowe. Przechowuje dłuższe, wielowierszowe teskty do 65535 znaków.


Spróbujmy teraz utworzyć tabelę do przechowywania adresów przyjaciół:

mysql> use nasza_baza
Database changed

mysql> CREATE TABLE adresy (
-> id INT NOT NULL auto increment,
-> imie VARCHAR(15) DEFAULT '<podaj imie>',
-> nazwisko VARCHAR(25) DEFAULT '<podaj nazwisko>',
-> adres BLOB,
-> PRIMARY KEY (id)
-> );
Query OK, 0 rows affected (0.06 sec)

mysql>


Właśnie utworzyliśmy tabelę adresy w bazie nasza_baza. Nowa tabela zawiera cztery pola. Pole id pełni funkcję klucza podstawowego (PRIMARY KEY), który jednoznacznie identyfikuje dany rekord. Jest ono typu auto_increment, co oznacza, że MySQL automatycznie będzie wstawiał do niego wartość o jeden większą, a po usunięciu któregoś z rekordów wartości nie przesuną się "w górę"; zawsze będą takiem same. Poza tym pole id nie może być puste (NOT NULL). Pola imie oraz nazwisko mają domyślnie wstawianą wartość, jeżeli nie została podana (DEFAULT).

Jeżeli chcesz obejrzeć strukturę tabeli użyj polecenia describe <nazwa tabeli>:

mysql> describe adresy;

+----------+-------------+------+-----+----------------+------------+

| Field | Type | Null | Key | Extra | Privileges |

+----------+-------------+------+-----+----------------+------------+

| id | int(11) | | PRI | auto_increment | zobacz * |

| imie | varchar(15) | YES | | | zobacz * |

| nazwisko | varchar(25) | YES | | | zobacz * |

| adres | blob | YES | | | zobacz * |

+----------+-------------+------+-----+----------------+------------+

4 rows in set (0.00 sec)

mysql>

* = select,insert,update,references
(użyte, aby zapis tabeli był bardziej czytelny)


MySQL wylistował nam wszystkie cztery pola, wyświeltił ich typy, klucze i wartości domyślne. Za pomocą tego polecenia możesz szybko zorientować się w strukturze każdej tabeli.

Możesz użyć również synonimicznej funkcji show columns from <nazwa_tabeli> dla wylistowania pól tabeli.

Sprawdźmy zatem co zwróci teraz polecenie show tables:

mysql> show tables;

+----------------------+

| Tables_in_nasza_baza |

+----------------------+

| adresy |

+----------------------+

1 row in set (0.05 sec)

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 <nazwa_tabeli>:

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).

Sprawdźmy jeszcze, jak wygląda struktura naszej tabeli po tych zmianach:

mysql> describe adresy;

+----------+-------------+------+-----+----------------+------------+

| Field | Type | Null | Key | Extra | Privileges |

+----------+-------------+------+-----+----------------+------------+

| id | int(11) | | PRI | auto_increment | zobacz * |

| imie | varchar(15) | YES | | | zobacz * |

| nazwisko | varchar(25) | YES | | | zobacz * |

| adres | blob | YES | | | zobacz * |

| email | varchar(80) | YES | | | zobacz * |

+----------+-------------+------+-----+----------------+------------+

5 rows in set (0.00 sec)

mysql>

* = select,insert,update,references
(użyte, aby zapis tabeli był bardziej czytelny)


Sróbujmy jeszcze dokonać dwu modyfikacji w strukturze naszej tabeli. Najpierw usuńmy pole nazwisko:

mysql> ALTER TABLE adresy DROP COLUMN nazwisko;

Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql>


A następnie dodajmy pole telefon, które ma występować bezpośrednio po polu adres:

mysql> ALTER TABLE adresy ADD telefon VARCHAR(15) AFTER adres;

Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0

mysql>


Aby dodać nowe pole po innym, używa się komendy AFTER. Aby natomiast dodać pole na początku tabeli, trzeba użyć komendy FIRST.

Spójrzmy jak teraz wygląda struktora naszej tabeli:

mysql> describe adresy;

+----------+-------------+------+-----+----------------+------------+

| Field | Type | Null | Key | Extra | Privileges |

+----------+-------------+------+-----+----------------+------------+

| id | int(11) | | PRI | auto_increment | zobacz * |

| imie | varchar(15) | YES | | | zobacz * |

| adres | blob | YES | | | zobacz * |

| telefon | varchar(15) | YES | | | zobacz * |

| email | varchar(80) | YES | | | zobacz * |

+----------+-------------+------+-----+----------------+------------+

5 rows in set (0.00 sec)

mysql>

* = select,insert,update,references
(użyte, aby zapis tabeli był bardziej czytelny)


I na koniec zmieńmy nazwę naszej tabeli z adresy na ksiazka_adresowa:

mysql> ALTER TABLE adresy RENAME ksiazka_adresowa;

Query OK, o rows affected (0.05 sec)

mysql>


Wyświetlmy teraz listę tabel w bazie nasza_baza:

mysql> show tables;

+----------------------+

| tables_in_nasza_baza |

+----------------------+

| ksiazka_adresowa |

+----------------------+

1 row in set (0.00 sec)

mysql>


Jak widać zmiana nazwy tabeli się powiodła.

USUWANIE TABELI

Przećwiczmy teraz usuwanie tabel, ale nie na tabeli ksiazka_adresowa, ponieważ przyda się nam ona później. Utwórzmy nową tabelę do_usuniecia z jednym polem o nazwie test:

mysql> CREATE TABLE do_usuniecia (
-> test CHAR(10)
-> );

Query OK, 0 rows affected (0.00 sec)

mysql>


Wyświetlmy listę tabel dla bazy nasza_baza:

mysql> show tables;

+----------------------+

| tables_in_nasza_baza |

+----------------------+

| do_usuniecia |

| ksiazka_adresowa |

+----------------------+

2 rows in set (0.00 sec)

mysql>


Usuńmy teraz tabele do_usuniecia za pomocą poznanej już komendy DROP z parametrem table <nazwa_tabeli>:

mysql> DROP TABLE do_usuniecia;

Query OK, 0 rows affected (0.00 sec)

mysql>


Sprawdźmy 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.



JĘZYK SQL

Ta część kursu przybliży Cię temat dodawania, wybierania, edycji i usuwania rekordów za pomocą języka SQL. Poznasz polecenia INSERT, SELECT, UPDATE i DELETE. W nazwach poleceń SQL wielkość liter nie ma znaczenia; możesz pisać polecenia małymi literami (co trochę przyspiesza pracę), w przykładach zostały jednak zastosowane wielkie litery dla zachowania czytelności kodu.

DODAWANIE REKORDÓW
Do dodawanie rekordów używa się polecenia INSERT. Spójrzmy na najprostszy przykład dodawania nowego rekordu do naszej książki adresowej w testowanej bazie danych:

mysql> INSERT INTO nasza_baza.ksiazka_adresowa VALUES(0,'Jan','ul. Wrocławska 5','888-55-41','jan@email.pl');

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:

W nawiasach okrągłych po słowie kluczowym VALUES wypisujemy listę wartości dla pól rekordu, który zamierzamy podać. Jakie i jakiego typu są te pola sprawdzimy znanym już poleceniem:

mysql> describe ksiazka_adresowa;

+----------+-------------+------+-----+--------------+----------------+

| Field | Type | Null | Key | Default | Extra |

+----------+-------------+------+-----+--------------+----------------|

| id | int(11) | | PRI | NULL | auto_increment |

| imie | varchar(15) | YES | | <podaj_imie> | |

| adres | blob | YES | | NULL | |

| telefon | varchar(15) | YES | | NULL | |

| email | varchar(80) | YES | | NULL | |

+----------+-------------+------+-----+--------------+----------------+

5 rows in set (0.00 sec)

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 '<podaj_imie>'. Ale co zrobić, żeby nie podać wartości dla danego pola? Możemy oczywiści postąpić tak (wtedy jednak wartość domyślna nie zostanie wstawiona):

mysql> INSERT INTO ksiazka_adresowa VALUES(0,'','ul Krakowska 16','777-33-84','zebra@zoo.pl');

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:

mysql> INSERT INTO ksiazka_adresowa(telefon, email) VALUES('471-84-36','my@email.pl');

Query OK, 1 row affected (0.06 sec)

mysql>

Spójrzmy co zwróci MySQL, gdy nie podamy wszystkich wartości, dla których zgłosiliśmy pola:

mysql> INSERT INTO ksiazka_adresowa(telefon, adres) VALUES('433-22-88');

ERROR 1136: Column count doesn't match value count at row 1

mysql>


Zwrócony komunikat świadczy o niezgodności listy pól z wartościami. rekord nie został dodany do naszej tabeli.
WYBIERANIE REKORDÓW

Chciałbyś pewnie wiedzieć, jak wygląda po tych operacjach nasza tabela ksiazka_adresowa. Jest na to sposób: polecenie SELECT, które służy do wybierania w rozmaity sposób rekordów z bazy danych. Podstawowa składnia tego polecenia wygląda następująco:

SELECT <lista_pól> FROM <nazwa_bazy>.<nazwa_tabeli>;


lub

SELECT <lista_pól> FROM <nazwa_tabeli>;


jeżeli wcześniej zostało użyte polecenie use <nazwa_bazy>. Spójrzmy zatem, co zwróci polecenie SELECT użyte w stosunku do naszej tabeli:

mysql> SELECT * FROM ksiazka_adresowa;

+----+--------------+--------------------+-----------+--------------+

| id | imie | adres | telefon | email |

+----+--------------+--------------------+-----------+--------------+

| 1 | Jan | ul. Wrocławska 5 | 888-55-41 | jan@email.pl |

| 2 | | ul Krakowska 16 | 777-33-84 | zebra@zoo.pl |

| 3 | <podaj imie> | ul. Warszawska 15 | 468-34-75 | NULL |

| 4 | <podaj imie> | NULL | 471-84-36 | my@email.pl |

+----+--------------+--------------------+-----------+--------------+

4 rows in set (0.00 sec)

mysql>


Jak widać wszystko, do dodawaliśmy, jest zapisane w naszej bazie danych. Znak * użyty zamiast listy pól oznacza, że chcemy wybrać wszystkie dostępne pola tabeli.

Spróbujmy teraz napisać takie polecenie SELECT, które poda nam tylko numery id i imiona:

mysql> SELECT id, imie FROM ksiazka_adresowa;

+----+--------------+

| id | imie |

+----+--------------+

| 1 | Jan |

| 2 | |

| 3 | <podaj imie> |

| 4 | <podaj imie> |

+----+--------------+

4 rows in set (0.00 sec)

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)

mysql>





Warunki

Warunki w zapytaniu SELECT umożliwiają dokładniejsze określanie, jakie rekordy mają zostać wybrane. Możesz wybrać na przykład rekord o numerze id równym 3. Jak zwykle w warunkach możesz używać operatorów porównania. Poniższa tabela przedstawia dostępne operatory dla warunków:

=

Równość

<>, !=

Nierówność

<

Mniejsze

>

Większe

<=

Mniejsze równe

>=

Większe równe


Spójrzmy ma przykład wybierający rekord o numerze id równym 3:

mysql> SELECT * FROM ksiazka_adresowa WHERE id = 3;

+----+--------------+-------------------+-----------+-------+

| id | imie | adres | telefon | email |

+----+--------------+-------------------+-----------+-------+

| 3 | <podaj imie> | ul. Warszawska 15 | 468-34-75 | NULL |

+----+--------------+-------------------+-----------+-------+

1 row in set (0.06 sec)

mysql>


Możesz oczywiście podawać więcej niż jeden warunek. Do łączenia warunków służą operatory logiczne, takie jak AND i OR:

mysql> SELECT id, imie, telefon FROM ksiazka_adresowa WHERE (id>=2 AND id<4) OR (imie='Jan');

+----+--------------+-----------+

| id | imie | telefon |

+----+--------------+-----------+

| 1 | Jan | 888-55-41 |

| 2 | | 777-33-84 |

| 3 | <podaj imie> | 468-34-75 |

+----+--------------+-----------+

3 rows in set (0.05 sec)

mysql>


Jak widać na powyższym przykładzie, grupy warunków umieszcza się w nawiasach.


Wyrażenie IN

Zamiast podawać grupy warunków dla wartości, które mogą znaleźć się w grupie wyników, można posłużyć się wyrażeniem IN. Spójrzmy najpierw na przykład wybierania rekordów zawierających numer id równy 1, 2 lub 4:

mysql> SELECT id, adres FROM ksiazka_adresowa WHERE id=1 OR id=2 OR id=4;

+----+--------------------+

| id | adres |

+----+--------------------+

| 1 | ul. Wrocławska 5 |

| 2 | ul Krakowska 16 |

| 4 | NULL |

+----+--------------------+

3 rows in set (0.00 sec)

mysql>


To samo można zapisać znacznie prościej za pomocą wyrażenie IN, które definiuje grupę dopuszczalnych wartości dla pola:

mysql> SELECT id, adres FROM ksiazka_adresowa WHERE id IN(1,2,4);

+----+--------------------+

| id | adres |

+----+--------------------+

| 1 | ul. Wrocławska 5 |

| 2 | ul Krakowska 16 |

| 4 | NULL |

+----+--------------------+

3 rows in set (0.00 sec)

mysql>


Jak widać użycie tego wyrażenia znacznie upraszcza zapytanie SQL.


Wyrażenie BETWEEN

Wyrażenie between (ang: pomiędzy) umożliwia określenie górnego i dolnego zakresu dla wartości pól rekordu. Spójrzmy najpierw na przykład wybierania rekordów o numerach id od 1 do 3 za pomocą standardowego WHERE:

mysql> SELECT id, telefon, email FROM ksiazka_adresowa WHERE id>=1 AND id<=3;

+----+-----------+--------------+

| id | telefon | email |

+----+-----------+--------------+

| 1 | 888-55-41 | jan@email.pl |

| 2 | 777-33-84 | zebra@zoo.pl |

| 3 | 468-34-75 | NULL |

+----+-----------+--------------+

3 rows in set (0.00 sec)

mysql>


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 | <podaj imie> | 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 | <podaj imie> | ul. Warszawska 15 |

| 4 | <podaj imie> | 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 | <podaj imie> | NULL |

| 3 | <podaj imie> | 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.

Możesz wpływać na kierunek sortowania za pomocą słów kluczowych ASC (domyślnie) i DESC (kirunek odwrotny). Spróbujmy zatem posortować numery id w odwrotnej kolejności:

mysql> SELECT id, imie, adres FROM ksiazka_adresowa ORDER BY id DESC;

+----+--------------+--------------------+

| id | imie | adres |

+----+--------------+--------------------+

| 4 | <podaj imie> | NULL |

| 3 | <podaj imie> | ul. Warszawska 15 |

| 2 | | ul Krakowska 16 |

| 1 | Jan | ul. Wrocławska 5 |

+----+--------------+--------------------+

4 rows in set (0.00 sec)

mysql>




Słowo kluczowe DISTINCT

Czasem zachodzi potrzeba, aby wśród podanych w jednej kolumnie wyników zapytania nie powtarzały się wartości. Do tego celu służy słowo kluczowe DISTINCT.

Spójrzmy najpierw na normalne wybieranie wartości kolumny imie:

mysql> SELECT imie FROM ksiazka_adresowa;

+--------------+

| imie |

+--------------+

| Jan |

| |

| <podaj imie> |

| <podaj imie> |

+--------------+

4 rows in set (0.00 sec)

mysql>


Jak widać wartość '<podaj imie>' występuje dwa razy. Spójrzmy teraz na wynik po użyciu słowa kluczowego DISTINCT:

mysql> SELECT DISTINCT imie FROM ksiazka_adresowa;

+--------------+

| imie |

+--------------+

| Jan |

| |

| <podaj imie> |

+--------------+

3 rows in set (0.00 sec)

mysql>


Jak widać wartości się już nie powtarzają.


Porównanie LIKE

Porównanie LIKE umożliwia tworzenie wzorców w zapytaniach. Spójrzmy na przykład wybierający pozycję w których pole imie na wartość '<podaj imie>', za pomocą typowego warunku WHERE:

mysql> SELECT id, imie FROM ksiazka_adresowa WHERE imie='<podaj imie>';

+----+--------------+

| id | imie |

+----+--------------+

| 3 | <podaj imie> |

| 4 | <podaj imie> |

+----+--------------+

2 rows in set (0.00 sec)

mysql>


A teraz za pomocą porównania LIKE:

mysql> SELECT id, imie FROM ksiazka_adresowa WHERE imie LIKE '<%>';

+----+--------------+

| id | imie |

+----+--------------+

| 3 | <podaj imie> |

| 4 | <podaj imie> |

+----+--------------+

2 rows in set (0.00 sec)

mysql>


Jak widać, wynik jest ten sam, a możliwości większe. Znak % zonacza dowolny ciąg znaków, natomiast znak _ oznacza dokładnie jeden znak:

mysql> SELECT id, imie, adres FROM ksiazka_adresowa WHERE imie LIKE '_an';

+----+------+------------------+

| id | imie | adres |

+----+------+------------------+

| 1 | Jan | ul. Wrocławska 5 |

+----+------+------------------+

1 row in set (0.00 sec)

mysql>




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 | <podaj imie> | 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 <nazwa_bazy>.<nazwa_tabeli> SET <nazwa_pola> = 'wartość' WHERE <warunek>


lub

UPDATE <nazwa_tabeli> SET <nazwa_pola> = 'wartość' WHERE <warunek>


jeżeli wcześniej zostało użyte polecenie use <nazwa_bazy>.

Spróbujmy zatem poprawić wartość pola adres, które ma id numer 2:

mysql> UPDATE ksiazka_adresowa SET adres = 'ul. Krakowska 16' WHERE id = 2;

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 |

+----+------+------------------+-----------+--------------+

1 row in set (0.00 sec)

mysql>



USUWANIE REKORDÓW

Na koniec zajmiemy się usuwaniem rekordów, Służy do tego celu polecenie DELETE, którego składnia przedstawia się następująco:

DELETE FROM <nazwa_bazy>.<nazwa_tabeli> WHERE <warunek>


lub

DELETE FROM <nazwa_tabeli> WHERE <warunek>


jeżeli wcześniej zostało użyte polecenie use <nazwa_bazy>.

Jeżeli warunek WHERE ... nie zostanie podany, zawartość całej tabeli zostanie usunięta.

Spróbujmy teraz usunąć rekord o id równym 3:

mysql> DELETE FROM ksiazka_adresowa WHERE id = 3;

Query OK, 1 row affected (0.06 sec)

mysql>


I spójrzmy jak teraz wygląda zawartość naszej tabeli 'ksiazka_adresowa':

mysql> SELECT * FROM ksiazka_adresowa;

+----+--------------+--------------------+-----------+--------------+

| id | imie | adres | telefon | email |

+----+--------------+--------------------+-----------+--------------+

| 1 | Jan | ul. Wrocławska 5 | 888-55-41 | jan@email.pl |

| 2 | | ul. Krakowska 16 | 777-33-84 | zebra@zoo.pl |

| 4 | <podaj imie> | NULL | 471-84-36 | my@email.pl |

+----+--------------+--------------------+-----------+--------------+

3 rows in set (0.00 sec)

mysql>


Jak widać, wartości numerów id nie przeindeksowały się (pole auto_increment), a następny numer id, jaki zostanie dodany, będzie miał wartość o jeden większą od największego, czyli 5.


UŻYTKOWNICY I UPRAWNIENIA

Ta część kursy przybliży ci temat określania uprawnień dla użytkowników bazy danych

System uprawnień w MySQL-u pozwala na dokładne zdefiniowanie praw dostępu do określonej bazy, tabeli czy kolumny.

JAK TO DZIAŁA

System uprawnień MySQL-a opiera się na pięciu tabelach znajdujących się w bazie mysql. Poniższy przykład prezentuje ich nazwy:

mysql> use mysql
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 |

Alter_priv |

+-----------+------+----------+-------------+-------------+-------------+

-------------+-------------+-----------+-------------+---------------+

--------------+-----------+------------+-----------------+------------+

------------+

| localhost | root | | Y | Y | Y |

Y | Y | Y | Y | Y |

Y | Y | Y | Y | Y

| Y |

| % | | | N | N | N |

N | N | N | N | N |

N | N | N | N | N

| N |

| localhost | | | Y | Y | Y |

Y | Y | Y | Y | Y |

Y | Y | Y | Y | Y

| Y |

| % | root | | Y | Y | Y |

Y | Y | Y | Y | Y |

Y | Y | Y | Y | Y

| Y |

+-----------+------+----------+-------------+-------------+-------------+

-------------+-------------+-----------+-------------+---------------+

--------------+-----------+------------+-----------------+------------+

------------+

4 rows in set (0.11 sec)

mysql>


Jak widać, tabela user zawiera cztery wpisy:


TABELA DB

Przyjrzyjmy się teraz bliżej tabeli db, która określa dostęp do bazy danych. Najpierw spójrzmy na strukturę tej tabeli:

mysql> describe db;

+-----------------+---------------+------+-----+-----+-------+-------+

| Field | Type | Null | Key | ()* | Extra | ()** |

+-----------------+---------------+------+-----+-----+-------+-------+

| Host | char(60) | | PRI | | | ()*** |

| Db | char(64) | | PRI | | | ()*** |

| User | char(16) | | PRI | | | ()*** |

| Select_priv | enum('N','Y') | | | N | | ()*** |

| Insert_priv | enum('N','Y') | | | N | | ()*** |

| Update_priv | enum('N','Y') | | | N | | ()*** |

| Delete_priv | enum('N','Y') | | | N | | ()*** |

| Create_priv | enum('N','Y') | | | N | | ()*** |

| Drop_priv | enum('N','Y') | | | N | | ()*** |

| Grant_priv | enum('N','Y') | | | N | | ()*** |

| References_priv | enum('N','Y') | | | N | | ()*** |

| Index_priv | enum('N','Y') | | | N | | ()*** |

| Alter_priv | enum('N','Y') | | | N | | ()*** |

+-----------------+---------------+------+-----+-----+-------+-------+

13 rows in set (0.11 sec)

mysql>


Objaśnienia:
* Default
** Privileges
*** select,insert,update,references


Jak widać, tabela ta zawiera pola dla nazwy hosta, bazy danych i użytkownika oraz listę pól z wartościami N lub Y dla określonych praw.

Spójrzmy co już zawiera ta tabela:

mysql> select * from user;

+-----------+-------+------+-------------+-------------+-------------+

-------------+-------------+-----------+------------+-----------------+

------------+------------+

| Host | Db | User | Select_priv | Insert_priv | Update_priv |

Delete_priv | Create_priv | Drop_priv | Grant_priv | References_priv |

Index_priv | Alter_priv |

+-----------+-------+------+-------------+-------------+-------------+

-------------+-------------+-----------+------------+-----------------+

------------+------------+

| % | test% | | Y | Y | Y |

Y | Y | Y | N | Y |

Y | Y |

+-----------+-------+------+-------------+-------------+-------------+

-------------+-------------+-----------+------------+-----------------+

------------+------------+

1 row in set (0.00 sec)

mysql>


Jak widać, tabela db zawiera jeden wpis:


TABELA HOST

Przyjrzyjmy się teraz bliżej tabeli host, która dokładniej definiuje przywileje zawarte w tabeli db. Najpierw spójrzmy na strukturę tej tabeli:

mysql> describe host;

+-----------------+---------------+------+-----+-----+-------+-------+

| Field | Type | Null | Key | ()* | Extra | ()** |

+-----------------+---------------+------+-----+-----+-------+-------+

| Host | char(60) | | PRI | | | ()*** |

| Db | char(64) | | PRI | | | ()*** |

| Select_priv | enum('N','Y') | | | N | | ()*** |

| Insert_priv | enum('N','Y') | | | N | | ()*** |

| Update_priv | enum('N','Y') | | | N | | ()*** |

| Delete_priv | enum('N','Y') | | | N | | ()*** |

| Create_priv | enum('N','Y') | | | N | | ()*** |

| Drop_priv | enum('N','Y') | | | N | | ()*** |

| Grant_priv | enum('N','Y') | | | N | | ()*** |

| References_priv | enum('N','Y') | | | N | | ()*** |

| Index_priv | enum('N','Y') | | | N | | ()*** |

| Alter_priv | enum('N','Y') | | | N | | ()*** |

+-----------------+---------------+------+-----+-----+-------+-------+

12 rows in set (0.05 sec)

mysql>


Objaśnienia:
* Default
** Privileges
*** select,insert,update,references


Jak widać, tabela ta zawiera pola dla nazwy hosta i bazy danych oraz listę pól z wartościami N i Y dla określonych praw.

Spójrzmy co już zawiera ta tabela:

mysql> select * from host;
Empty set (0.00 sec)

mysql>


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>


Jak widać, tabela columns_priv nie zawiera żadnych wpisów, ponieważ nie były jeszcze potrzebne tak dokładnie określone uprawnienia dostępu.

MANIPULACJA UPRAWNIENIAMI

Po dłuższym wstępie przejdźmy do nieco ciekawszej części, czyli nadawania uprawnień i ich odbierania. Wszelkie zmiany dotyczące tabel w bazie mysql możesz przeprowadzać za pomocą znanych ci z poprzedniej części kursy poleceń, takich jak select, insert, update czy delete. Możesz również w łatwy sposób zarządzać uprawnieniami za pomocą poleceń GRANT (dodawanie uprawnień) i REVOKE (odbieranie uprawnień).

Na początku ustawmy hasło dla użytkownika root, aby nikt niepowołany nie mógł w łatwy sposób dostać się do serwera baz danych:

mysql> UPDATE user SET Password=PASSWORD('pass') WHERE user='root';
Query OK, 2 rows affected (0.05 sec)
Rows matched: 2 Changed: 2 Warnings: 0

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

mysql>


Za pomocą polecenia UPDATE zmieniliśmy wartość pola Password na nowe hasło, tam gdzie użytkownik jest zdefiniowany jako root (dwa rekordy). Hasła w MySQL kodowane są za pomocą funkcji PASSWORD(), dlatego musisz jej użyć, aby zapisać hasło w tabeli.

Ostatnie polecenie (FLUSH PRIVILEGES;) przeładowuje uprawnienia. Gdybyśmy tego nie zrobili, zmiany nie byłyby widoczne, root dalej logowałby się bez hasła. Nie musisz odświeżać uprawnień, jeżeli używasz wbudowanych funkcji do obsługi przywilejów:

mysql> SET PASSWORD FOR root=PASSWORD('mypass');
Query OK, 0 rows affected (0.05 sec)

mysql>


Spróbujmy teraz zalogować się do mysql-a z hasłem 'pass':

C:\apache\mysql\bin> mysql -u root -p
Enter password: ****
ERROR 1045: Access denied for user: 'root@localhost' (using password: YES)

C:\apache\mysq\bin>


Jak widać hasło 'pass' nie jest już aktualne, ponieważ zmieniliśmy je na 'mypass' za pomocą funkcji SET PASSWORD...

Spróbujmy zatem jeszcze raz, tym razem podając haslo 'mypass':

C:\apache\mysql\bin> mysql -u root -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 40 to server version: 3.23.33

Type 'help' for help

mysql>


I spróbujmy jeszcze zalogować się bez hasła, jak dawniej:

C:\apache\mysql\bin> mysql -u root
ERROR 1045: Access denied for user 'root@localhost' (Using password: NO)

C:\apache\mysql\bin>


Jak wiadć, nasz MySQL jest zabezpieczony hasłem.



Polecenie GRANT

Za pomocą tego polecenia dodajesz uprawnienia dostępu do baz danych, tabel czy kolumn.

Spróbujmy teraz utworzyć nowego użytkownika admin z dostępem do bazy danych nasza_baza i tabeli ksiazka_adresowa:

mysql> GRANT SELECT ON nasza_baza.ksiazka_adresowa TO admin@localhost;
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 <dowolna_baza>.<dowolna_tabela>:.

Spróbujmy teraz utworzyć użytkownika admin4 przychodzącego z dowolnego hosta z prawem wybierania rekordów z bazy nasza_baza i dowolnej tabeli:

mysql> GRANT SELECT ON nasza baza.* TO admin4@'%';
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.

Spróbujmy jeszcze utworzyć takiego użytkownika jak poprzedni, ale z prawem nadawania uprawnień (grantów):

mysql> GRANT ALL PRIVILEGES ON nasza_baza.* TO admin6@localhost WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql>


Jak widać, aby zaznaczyć, że chchcemy nadać wszystkie prawa razem z grantami, użyliśmy polecenia WITH GRANT OPTION.

Spróbujmy teraz utworzyć użytkownika admin7 z dostępem do wszystkich baz danych i tabel, ale z wymaganym hasłem 'haslo':

mysql> GRANT ALL PRIVILEGES ON *.* TO admin7@localhost IDENTIFIED BY 'haslo';
Query OK, 0 rows affected (0.00 sec)

mysql>


Spróbujmy teraz zalogować się na użytkownika admin7, raz bez podania hasła, a następnie z hasłem:

C:\apache\mysql\bin> mysql -u admin7
ERROR 1045: Access denied for user: 'admin7@localhost' (Using password: NO)

C:\apache\mysq\bin> mysql -u admin7 -p
Enter password: *****
Welcome to the MySQl monitor. Commands with ; or \g.
Your MySQL connection id is 78 to server version: 3.23.33

Type 'help' for help.

mysql>


Jak widać hasło dla tego użytkownika jest wymagane.

Spróbujmy jeszcze utworzyć użytkownika admin8 z prawem wybierania pola imie oraz edycji pól adres i email z tabeli ksiazka_adresowa w naszej baze testowej:

mysql> GRANT SELECT(imie),UPDATE(adres,email) ON nasza_baza.ksiazka_adresowa TO admin8@localhost;
Query OK, 0 rows affected (0.22 sec)

mysql>


Jak widać, aby określić kolumny, na jakich mają działać uprawnienia, wystarczy zapisać je w nawiasach okrągłych występujących po uprawnieniu.


Polecenie REVOKE

Za pomocą tego polecenia usuwasz uprawnienia dostępu do baz danych, tabel czy kolumn.

Spróbujmy teraz usunąć uprawnienia nadane użytkownikowi admin z dostępem do bazy danych nasza_baza i tabeli ksiazka_adresowa:

mysql> REVOKE SELECT ON nasza_baza.ksiazka_adresowa FROM admin@localhost;
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>




7



Wyszukiwarka