← Lekcje
PHP · lekcja 16

Formularze 1/2: odbiór danych z formularza

Dzisiaj:

  1. Formularz HTML wysyła dane do serwera na dwa sposoby: method="get" albo method="post"
  2. Serwer odbiera te dane w tablicy $_GET albo $_POST
  3. Klucze tej tablicy to atrybuty name pól formularza
  4. Ćwiczenie: contact.html i contact.php odczytujący $_POST["userName"]
Rozgrzewka · 3 minuty

Rozgrzewka: public, private, protected

  1. Czym różni się public od private?
  2. Co się stanie, gdy spróbujesz odczytać właściwość private spoza klasy?
  3. Po co potrzebna jest metoda getPrice(), skoro $price jest teraz private?
Część 1 · Droga danych z formularza

Jak dane trafiają z formularza do PHP?

Do tej pory PHP działał sam, bez żadnych danych od użytkownika. Formularz HTML to sposób, żeby użytkownik podał przeglądarce jakieś dane, a przeglądarka przesłała je dalej na serwer. Cała wymiana idzie przez HTTP (ang. Hypertext Transfer Protocol) - protokół, którym przeglądarka i serwer wysyłają do siebie żądania i odpowiedzi, jak wcześniej przy każdym zwykłym wejściu na stronę.

formularz w przeglądarce użytkownik wpisuje dane żądanie HTTP GET / POST żądanie niesie dane z pól formularza skrypt PHP na serwerze czyta $_GET / $_POST odpowiedź HTML z powrotem do przeglądarki
PHP Manual: „An associative array of variables passed to the current script via the HTTP POST method” · php.net/manual/en/reserved.variables.post.php
Część 2 · GET czy POST

method="get" czy method="post"?

Atrybut method formularza wybiera jedną z dwóch metod HTTP. GET (ang. „pobierz”) dokleja dane do adresu strony, po znaku ? - widać je w pasku adresu, ale mieszczą się tylko krótkie wartości. POST (ang. „wyślij”) chowa dane w treści (ciele) żądania - w adresie nic nie widać, mieści się więcej danych, tak wysyła się np. hasła.

GET - dane w adresie contact.php?userName=Jan POST - dane w treści żądania contact.php treść żądania (niewidoczna w adresie) userName=Jan userMessage=Czesc

Ciekawostka z MDN: metoda GET ma tylko pobierać dane, nie zmieniać niczego na serwerze - dlatego przeglądarka może bezpiecznie zapamiętać odpowiedź na żądanie GET w pamięci podręcznej (ang. cache). Metoda POST zwykle coś na serwerze zmienia, więc przeglądarki takich odpowiedzi zwykle nie zapamiętują.

PHP Manual: „An associative array of variables passed to the current script via the URL parameters (also known as the query string)” · php.net/manual/en/reserved.variables.get.php · ciekawostka: MDN, „Requests using GET should only retrieve data and should not contain a request content”; tabela „Safe, idempotent, and cacheable request methods” (GET: cacheable - Yes, POST: cacheable - Conditional) · developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods
Część 3 · $_POST jako tablica

$_POST: klucze to nazwy pól

Każde pole formularza ma atrybut name. PHP odbiera dane w tablicy asocjacyjnej (kluczami są teksty, nie numery). Kluczem każdej wartości jest właśnie ten atrybut name, nie treść pola ani jego etykieta.

<input name="userName"> <input name="userMessage"> $_POST [userName] => Jan [userMessage] => Czesc
PHP Manual: reserved.variables.post.php (tablica asocjacyjna) · php.net/manual/en
Część 4 · Kod na żywo

contact.html i contact.php

<!-- contact.html -->
<form action="contact.php" method="post">
  <input type="text" name="userName">
  <input type="text" name="userMessage">
  <button>Wyślij</button>
</form>
// contact.php
$name = $_POST["userName"];
$message = $_POST["userMessage"];
echo "Dziękujemy, " . $name . "! Otrzymaliśmy wiadomość: " . $message;
// Dziękujemy, Jan! Otrzymaliśmy wiadomość: Czesc
PHP Manual: reserved.variables.post.php · php.net/manual/en
Egzamin INF.03

Tak pytają na egzaminie

1. W formularzu dokumentu PHP istnieje pole <input name="im">. Po wprowadzeniu przez użytkownika ciągu znaków „Janek”, w celu dodania zawartości pola do bazy danych, w tablicy $_POST zawarty jest element

  1. im o indeksie Janek.
  2. Janek o indeksie im.
  3. im z kolejnym numerem indeksu.
  4. Janek z kolejnym numerem indeksu.
CKE, E.14, styczeń 2018, zadanie 35
Ćwiczenie przy komputerze · 15 minut

Ćwiczenie: contact.html i contact.php

  1. W folderze swojego serwera (np. htdocs) utwórz plik contact.html z formularzem: dwa pola <input> o nazwach name="userName" i name="userMessage", atrybuty action="contact.php" i method="post".
  2. Utwórz plik contact.php, który odczytuje $_POST["userName"] i $_POST["userMessage"] i wypisuje je przez echo.
  3. Otwórz localhost/contact.html, wypełnij formularz i sprawdź, że po kliknięciu przycisku pojawiają się wpisane dane.
  4. Spróbuj zmienić w contact.html method="post" na method="get", wyślij formularz jeszcze raz i zobacz dane w adresie strony - potem wróć do method="post".

Ma się pojawić: po wysłaniu formularza strona contact.php z tekstem w stylu „Dziękujemy, [Twoje imię]! Otrzymaliśmy wiadomość: [Twoja wiadomość]”.

Całe pliki
<!-- contact.html -->
<!DOCTYPE html>
<html lang="pl">
<head><meta charset="utf-8"><title>Kontakt</title></head>
<body>
  <form action="contact.php" method="post">
    <label>Imię: <input type="text" name="userName"></label><br>
    <label>Wiadomość: <input type="text" name="userMessage"></label><br>
    <button type="submit">Wyślij</button>
  </form>
</body></html>

// contact.php
$name = $_POST["userName"];
$message = $_POST["userMessage"];
echo "Dziękujemy, " . $name . "! Otrzymaliśmy wiadomość: " . $message;
// przy userName=Jan, userMessage=Czesc: Dziękujemy, Jan! Otrzymaliśmy wiadomość: Czesc
Na koniec

Sprawdź się

  1. Czym różni się method="get" od method="post"?
  2. Skąd biorą się klucze w tablicy $_POST?
  3. Dlaczego hasła nie wysyła się metodą GET?

To była pierwsza lekcja tematu formularzy - na następnej: sprawdzanie, czy pole nie jest puste.

Poza szkołą

A jak to wygląda w produkcji?

Na lekcjiW produkcjiStatus
Odczyt pola wprost przez $_POST["userName"]Dane z formularza zawsze się sprawdza i oczyszcza przed użyciem (np. filter_var, walidacja długości) - surowy $_POST może zawierać cokolwiek, także złośliwy kod.nadal w użyciu (z dodatkową walidacją, temat następnej lekcji)
Formularz z dwoma zwykłymi polami tekstowymiFrameworki (np. Laravel) mają gotowe klasy do formularzy z automatyczną walidacją i komunikatami błędów po polsku czy angielsku.zastępowane (frameworkiem)
method="get" pokazany tylko jako ciekawostkaGET nadal jest podstawą wyszukiwarek i filtrów na stronach (adres można zapisać w zakładkach) - POST dominuje tam, gdzie dane zmieniają coś na serwerze (logowanie, zamówienie).nadal w użyciu (oba, do różnych celów)
PHP Manual: reserved.variables.get.php, reserved.variables.post.php