PHP/Formularze: Różnice pomiędzy wersjami
Usunięta treść Dodana treść
Styl. |
dodanie ustępu o protokole HTTP i korekta formatowania |
||
Linia 1:
{{prognaw|PHP|[[../Zmienne i tablice/]]|[[../Struktury kontrolne/]]}}
== Formularze ==
W tym rozdziale zajmiemy się podstawami komunikacji skryptu PHP z przeglądarką.
=== Protokół HTTP ===
[[Plik:Http-request-pl.png|400px|thumb|Działanie protokołu HTTP.]]
Podstawą funkcjonowania stron WWW jest protokół HTTP, którego używa przeglądarka i serwer. Zasada jego działania jest bardzo prosta. Gdy chcemy obejrzeć dokument pod podanym adresem URL, wysyłamy do serwera tzw. '''żądanie HTTP''' zawierające lokalizację zasobu oraz garść informacji o nas samych. Serwer odnajduje lub generuje (np. przy pomocy PHP) odpowiedni dokument i odsyła wszystko jako '''odpowiedź HTTP'''. Odpowiedź zawsze zawiera pewną ilość nagłówków informacyjnych oraz opcjonalną treść, w której przesyłany jest dokument. Przeglądarka odbiera wszystko i rozpoczyna działanie. Protokół jest stosowany zarówno do pobierania kodu HTML strony, jak i znajdujących się na niej obrazków, ściągania plików i innych danych multimedialnych. Rodzaj pobieranej zawartości jest określany przez nagłówki.
Skrypty PHP zawsze pracują po stronie serwera, generując odpowiedzi HTTP na przychodzące do niego żądania. Przeważnie koncentrujemy się jedynie na budowaniu treści, ponieważ interpreter potrafi samodzielnie skonstruować podstawowy zestaw odpowiednich nagłówków, który co najwyżej uzupełniamy. Bardzo często do wygenerowania strony potrzebne są dodatkowe informacje, które najczęściej przechowywane są w bazie danych, a rzadziej - w plikach. Skrypty pobierają z nich dane, poddają je obróbce i osadzają w kodzie HTML, który jest odsyłany do klienta.
{{Uwaga|Gdy przeglądarka zaczyna wyświetlać dokument, skrypt PHP już dawno skończył swoją pracę. Pamiętaj, że działanie Twoich skryptów nie może wykroczyć poza ramy protokołu HTTP, w szczególności reagować na zdarzenia w przeglądarce (np. kliknięcie myszką), ani modyfikować fizycznie wysłanej treści. Do takich celów wykorzystywane są inne języki i technologie: JavaScript, AJAX.}}
Istotną częścią protokołu HTTP są rodzaje żądań (zwane "metodami") informujące o tym, co próbujemy zrobić. Dwa podstawowe to:
# Żądania '''GET''' - zwyczajne pobieranie dokumentu z serwera.
# Żądania '''POST''' - wysłanie pewnych danych na serwer.
Istnieją jeszcze inne metody, które są coraz powszechniej stosowane w większych aplikacjach WWW, jednak na niektórych serwerach są one z nieznanych powodów poblokowane. Protokołem HTTP zajmiemy się dokładniej w dalszej części podręcznika, tymczasem na razie będą nas interesować te dwie. Pierwsza z nich jest wykorzystywana podczas zwykłego pobierania z serwera dokumentu, natomiast druga - przy formularzach.
=== Ogólnie o danych wejściowych ===
W żądaniu HTTP przenoszonych jest wiele informacji o tym, co użytkownik chce obejrzeć oraz o nim samym. Wielu danych dostarcza także sam serwer HTTP. Wszystkie one są podstawą dla aplikacji PHP do wygenerowania odpowiedzi. Mechanizm ich odbierania ewoluował stopniowo. Pierwsze wersje języka rejestrowały wszystkie nadesłane parametry, dane formularzy itd. jako zmienne, lecz było to wyjątkowo niebezpieczne. Dodając nowe parametry można było rejestrować nowe zmienne, które mogły nadpisać zmienne używane w kodzie aplikacji powodując jego błędne działanie (np. zyskanie praw administratora strony przez atakującego). Programista nie mógł także policzyć, ile danych właściwie trafiało do skryptu i gdzie są one zawarte.
Wszystko zmieniło się wraz z pojawieniem się PHP4. Obecnie wszystkie pola są rejestrowane w specjalnych, tworzonych przez skrypt tablicach asocjacyjnych posegregowane według miejsca, z którego nadeszły. PHP potrafi odbierać informacje:
* Charakterystyczne dla metody GET (adresy URL)
* Charakterystyczne dla metody POST (zawartość formularzy)
* z serwera
* z ciasteczek
Linia 19 ⟶ 36:
=== Adresy URL ===
Przyjrzymy się zawartości tablicy:
var_dump($_GET);
</source>
Wywołując skrypt normalnie: http://localhost/~programowanie_php/nazwaskryptu.php otrzymamy następujący rezultat:
Linia 35 ⟶ 49:
array(0) { }
Oznacza to, że nie otrzymaliśmy tą
array(1) { ["parametr"]=> string(7) "wartosc" }
Linia 43 ⟶ 57:
Napiszemy teraz prosty skrypt wyświetlający informacje powitalne na podstawie danych z adresu:
if(sizeof($_GET) == 2)
{
echo 'Witaj, '.$_GET['imie'].' '.$_GET['nazwisko'].'!';
}
else
{
echo 'Nieprawidłowa liczba parametrów!';
}
</source>
Nie przejmuj się istnieniem konstrukcji, której jeszcze nie poznaliśmy. Niektórzy pewnie domyślili się, co ona robi, ale szczegóły będą podane już w następnym rozdziale. Na razie wpiszmy ją tak, jak jest. Funkcja <code>sizeof()</code> pojawiająca się w kodzie zwraca ilość elementów w tablicy. Sprawdzamy w ten sposób, czy użytkownik podał to, co trzeba. Kontrola nadchodzących danych jest niezwykle istotna i '''nigdy''' nie wolno jej zlekceważyć. Pominięcie tego aspektu zazwyczaj kończy się dla skryptu tragicznie, bo jeżeli coś jest do zepsucia, na pewno znajdzie się ktoś, kto tego dokona.
Wywołując skrypt z parametrami "imie" oraz "nazwisko" możemy wpływać na wyświetlane informacje: [http://localhost/~programowanie_php/nazwaskryptu.php?imie=Adam&nazwisko=Kowalski http://localhost/~programowanie_php/nazwaskryptu.php?imie=Adam&nazwisko=Kowalski]. Dla lepszego efektu stwórzmy prosty formularz HTML wysyłający dane metodą GET:
<source lang="html4strict"><?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
Linia 79 ⟶ 91:
</form>
</body>
</html
</source>
Choć tworzenie formularzy teoretycznie pasuje do następnej sekcji, tak naprawdę w tym momencie zwyczajnie oszukujemy. Wypełnij ten formularz i wyślij go, a zobaczysz, że przeglądarka dokleiła do pliku podanego w znaczniku FORM parametry utworzone na podstawie pól! Tak więc nasz skrypt nawet nie ma możliwości stwierdzenia, skąd dane do niego przyszły! Poznajmy zatem metodę POST...
=== Formularze ===
Obsługa formularzy z prawdziwego zdarzenia, którymi można przesyłać setki informacji, odbywa się dosyć podobnie, jak adresów. Różnica jest taka, że wszystko wysyła się wyłącznie z formularza, który posiada parametr "method" ustawiony na "post" oraz że korzysta się z tablicy <code>$_POST</code> wewnątrz samego skryptu. Przeróbmy nasze ostatnie dzieło tak, aby pracowało w ten sposób.
<source lang="php"><?php
if(count($_POST) == 2)
{
echo 'Witaj, '.$_POST['imie'].' '.$_POST['nazwisko'].'!';
}
else
{
echo 'Nieprawidłowa liczba parametrów!';
}
</source>
W skrypcie podmieniamy jedynie nazwy tablic na <code>$_POST</code>. W formularzu musimy jeszcze zmienić metodę:
<source lang="html4strict"><html>
<head>
<title>Formularz HTML</title>
</head>
<body>
<form method="post" action="nazwaskryptu.php">
Podaj imię: <input type="text" name="imie"/><br/>
Podaj nazwisko: <input type="text" name="nazwisko"/><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
</source>
I gotowe. Wyślij teraz formularz. Zauważ, że żadna informacja nie jest doklejana do adresu, ponieważ transmisja odbywa się niejako innym kanałem.
{{Infobox|Nazwy tablic są trochę nieprecyzyjne. To, że wysłaliśmy żądanie metodą POST wcale nie oznacza, że tablica <code>$_GET</code> będzie wtedy zawsze pusta. Możliwe jest jednocześne wysłanie danych formularzem wraz ze zmiennymi w adresie URL, co sprawi, że obie tablice będą posiadać jakąś zawartość.}}
Z kursów języka HTML wiadomo, że istnieją różne typy pól formularzy. Oto, jakie wartości otrzymuje od nich PHP:
* <pre><nowiki><input type="text" name="nazwa"/></nowiki></pre> - skrypt otrzymuje
* <pre><nowiki><input type="hidden" name="nazwa"/></nowiki></pre> - skrypt otrzymuje
* <pre><nowiki><input type="radio" name="nazwa" value="wartosc"/></nowiki></pre> - pozycje należące do tej samej grupy muszą mieć identyczną nazwę.
* <pre><nowiki><input type="checkbox" name="nazwa"/></nowiki></pre> - jeśli pole jest zaznaczone,
* <pre><nowiki><select name="nazwa">...</select></nowiki></pre> -
* <pre><nowiki><input type="submit" name="nazwa"/></nowiki></pre> - zmienna
Dzięki temu można do formularzy wstawiać kilka przycisków "submit"
i reagować inaczej w zależności od tego, który z nich został naciśnięty.
Linia 130 ⟶ 145:
Na sam koniec zostawiliśmy sobie kilka informacji przekazywanych interpreterowi przez serwer WWW (np. Apache). Zacznijmy od określenia adresu IP gościa:
echo 'Witaj, twój adres IP to '.$_SERVER['REMOTE_ADDR'].'!';
</source>
Ten skrypt pokaże nam adres IP komputera lub sieci, w której znajduje się internauta. W tym drugim przypadku dalsze informacje są niepewne. Serwerowi potrzebny jest wyłącznie ten adres, aby móc gdzieś wysłać rezultat, a pola <code>$_SERVER['HTTP_X_FORWARDED_FOR']</code> lub <code>$_SERVER['HTTP_CLIENT_IP']</code> są bardzo niepewne - generuje je właśnie serwer proxy, ale nic nie stoi na przeszkodzie, by podszył się pod nie hacker. Uznawanie ważności informacji tu zawartych było przyczyną wielu błędów bezpieczeństwa w popularnym skrypcie forów dyskusyjnych phpBB i jeżeli naprawdę zależy Ci na nim, pozostań przy ''REMOTE_ADDR'', a resztę traktuj wyłącznie jako ciekawostkę.
Korzystając z funkcji <code>gethostbyaddr()</code> możemy uzyskać nazwę hosta, którego dotyczy adres IP:
<source lang="php"><?php
echo 'Witaj, twój host to '.gethostbyaddr($_SERVER['REMOTE_ADDR']).'!';
</source>
Spróbujmy zidentyfikować przeglądarkę użytkownika:
echo 'Twoja przeglądarka została zidentyfikowana jako: '.$_SERVER['HTTP_USER_AGENT'].'!';
</source>
Pole to zawiera wyłącznie surowe informacje. Każda przeglądarka wpisuje tu co innego i dlatego wyciągnięcie ładnych i pogrupowanych w odpowiednie kategorie danych to zadanie na więcej, niż jeden artykuł. Pozostańmy zatem przy takiej postaci, a przetwarzaniem nagłówków przeglądarek zajmiemy się kiedy indziej.
Adres strony, z której przybyliśmy do naszego skryptu, znajduje się w zmiennej
Uwaga: nie można polegać na obecności i prawidłowości tej informacji. Istnieją przeglądarki i zapory ogniowe, które ją usuwają lub wstawiają tam dowolny adres podany przez użytkownika.
echo 'Przybyłeś do nas ze strony: '.$_SERVER['HTTP_REFERER'].'!';
</source>
W chwili obecnej to tyle, jeżeli chodzi o pobieranie danych. Dalszych informacji dowiemy się w trakcie następnych rozdziałów w miarę potrzeby.
|