Skąd PHP bierze dane z formularza

PHP działa na serwerze i nie widzi, co użytkownik wpisuje w przeglądarce. Dane muszą dojechać w żądaniu. Cała droga to cztery kroki:

1
Użytkownik wypełnia formularz i klika przycisk submit.
2
Przeglądarka wysyła żądanie do adresu z atrybutu action. Jeśli go nie ma, wysyła na tę samą stronę. Metoda (get albo post) decyduje, w którym miejscu żądania jadą dane.
3
Serwer uruchamia PHP, a ono układa dane w tablice $_GET albo $_POST. Kluczem jest atrybut name pola, wartością to, co wpisał użytkownik.
4
Twój kod czyta tablicę, coś z danymi robi i wypisuje wynik. Przeglądarka dostaje gotowy HTML.

Wniosek, który warto zapamiętać: bez atrybutu name pole nie wyśle nic. Atrybut id do tego nie służy.

<input type="text" name="imie">     <!-- w PHP: $_GET['imie'] albo $_POST['imie'] -->

GET czy POST, kiedy który

GET

Dane lądują w adresie po znaku zapytania:

strona.php?imie=Ola&wiek=17

Każde pole to para name=wartość, pary łączy znak &. Adres można zapisać w zakładkach i wysłać komuś. Przydaje się przy wyszukiwarkach, filtrach i sortowaniu.

POST

Dane jadą w treści żądania i nie ma ich w adresie:

strona.php

Nadaje się do logowania, rejestracji, formularzy kontaktowych i wszystkiego, co coś zapisuje lub zmienia na serwerze.

GETPOST
Odczyt w PHP$_GET['pole']$_POST['pole']
Dane widać w adresietaknie
Odświeżenie strony (F5)bez problemuprzeglądarka pyta o ponowne wysłanie
Hasła i dane prywatnenigdytak, ale i tak najlepiej przez HTTPS
Limit długościkrótki (adres nie może być dowolnie długi)praktycznie brak

POST nie szyfruje danych. Ukrywa je tylko przed paskiem adresu i historią przeglądarki. Bezpieczeństwo zapewnia dopiero HTTPS.

Jak używać danych: cztery zasady

Wszystko, co przychodzi z formularza, pisze użytkownik, a użytkownik może wpisać cokolwiek albo w ogóle nic. Dlatego każdy odczyt przechodzi cztery etapy:

1. Sprawdź, czy dane w ogóle przyszły

Bez tego przy pierwszym wejściu na stronę dostaniesz ostrzeżenie Undefined array key.

if (isset($_GET['imie'])) { ... }

2. Pobierz do zmiennej i oczyść

trim() usuwa spacje z początku i końca. Wartość z formularza to zawsze tekst, nawet jeśli pole ma type="number".

$imie = trim($_GET['imie']);

3. Sprawdź i zamień na właściwy typ

if ($imie === '') { echo "Wpisz imię"; }
$wiek = (int)$_GET['wiek'];              // liczba całkowita
is_numeric($_GET['a']);                 // czy to w ogóle liczba
filter_var($email, FILTER_VALIDATE_EMAIL); // czy to adres e-mail

4. Wypisz bezpiecznie

htmlspecialchars() zamienia znaki takie jak < i > na zwykły tekst. Bez tego ktoś wpisze w pole imię <script> i uruchomi swój kod u każdego, kto zobaczy stronę. To atak XSS. Zasada jest prosta: co przyszło od użytkownika, przechodzi przez htmlspecialchars() przed wypisaniem.

echo "Cześć " . htmlspecialchars($imie);

Jak sprawdzić, który formularz wysłano

Gdy na stronie jest kilka formularzy, nadaj przyciskowi submit nazwę i sprawdzaj ją: isset($_POST['wyslij_post']). To robią ćwiczenia poniżej. Pod każdym z nich zobaczysz ramkę z tym, co naprawdę dotarło do serwera, więc od razu widać różnicę między GET i POST.

Typowe błędy

Pole nic nie wysyła. Brakuje atrybutu name albo nazwa w PHP różni się od nazwy w HTML (imie to nie Imie, wielkość liter ma znaczenie).

Ostrzeżenie Undefined array key. Odczyt bez isset() przy pierwszym wejściu na stronę, kiedy formularz jeszcze nie został wysłany.

Hasło w GET. Trafia do adresu, historii przeglądarki i logów serwera. Hasła zawsze w POST.

Wypisanie danych bez htmlspecialchars. Strona działa, dopóki nikt nie wpisze w pole kodu HTML.

Zaufanie do required. Działa tylko w przeglądarce. Serwer i tak musi sprawdzić dane sam.

Dodawanie tekstów zamiast liczb. Zapomnienie o (int) albo is_numeric(). W nowszych wersjach PHP tekst zamiast liczby przy dodawaniu kończy się błędem.

8

Formularz GET

GET

Formularz GET. Pobierz imię i wiek i wyświetl komunikat: Cześć [imię], masz [wiek] lat.

Na własną rękę: Dodaj poprawną odmianę: 1 rok, 2 lata, 5 lat. Wskazówka: reszta z dzielenia (%) przez 10 i przez 100.

Wypróbuj

Kod do przepisania

<form method="get">
  Imię: <input type="text" name="imie" required><br>
  Wiek: <input type="number" name="wiek" required><br>
  <input type="submit" name="wyslij_get" value="Wyślij">
</form>
<?php
if (isset($_GET['wyslij_get'])) {
    $imie = htmlspecialchars($_GET['imie']);
    $wiek = (int)$_GET['wiek'];
    echo "Cześć $imie, masz $wiek lat";
}
?>
9

Formularz POST

POST

Formularz POST. Pobierz nazwę użytkownika i hasło i wyświetl komunikat: Witaj [nazwa].

Na własną rękę: Sprawdź, czy hasło ma co najmniej 8 znaków (strlen()). Hasła nigdy nie wypisujemy na stronie.

Wypróbuj

Kod do przepisania

<form method="post">
  Nazwa użytkownika: <input type="text" name="nazwa" required><br>
  Hasło: <input type="password" name="haslo" required><br>
  <input type="submit" name="wyslij_post" value="Wyślij">
</form>
<?php
if (isset($_POST['wyslij_post'])) {
    $nazwa = htmlspecialchars($_POST['nazwa']);
    echo "Witaj $nazwa";
}
?>
10

GET vs POST

GET + POST

Dwa formularze, jeden GET i jeden POST, oba liczą sumę dwóch liczb. Wynik zależy od tego, którego użyjesz.

Na własną rękę: Wyślij GET, potem POST, potem znów GET. Co się dzieje z wynikiem tego drugiego formularza i dlaczego?

Wypróbuj

Kod do przepisania

<form method="get">
  Liczba 1: <input type="number" name="a" required><br>
  Liczba 2: <input type="number" name="b" required><br>
  <input type="submit" name="suma_get" value="Oblicz GET">
</form>

<form method="post">
  Liczba 1: <input type="number" name="c" required><br>
  Liczba 2: <input type="number" name="d" required><br>
  <input type="submit" name="suma_post" value="Oblicz POST">
</form>

<?php
if (isset($_GET['suma_get'])) {
    $a = (int)$_GET['a'];
    $b = (int)$_GET['b'];
    echo "Suma GET: " . ($a + $b);
}
if (isset($_POST['suma_post'])) {
    $c = (int)$_POST['c'];
    $d = (int)$_POST['d'];
    echo "Suma POST: " . ($c + $d);
}
?>