13. PHP – odbieranie danych z przeglądarki – formularze html, metody GET i POST. Wysyłanie danych do przeglądarki.


Przykład z formularzem

Poniżej znajduje się przykład przedstawiający zapis danych do pliku z formularza. Formularz przesyła dane metodą POST.

Dane zapisywane do pliku są zbierane w zmiennej $info.

Plik formularz.php

<?php
// Debugowanie - wyświetl dane POST
/*
echo "<pre>";
print_r($_POST);
echo "</pre>";
*/

$info = '';
$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['przycisk'])) {
    // Walidacja
    if (empty($_POST['imie'])) {
        $errors[] = "Imię jest wymagane";
    }
    
    if (empty($_POST['nazwisko'])) {
        $errors[] = "Nazwisko jest wymagane";
    }
    
    // Jeśli są błędy, wyświetl
    if (!empty($errors)) {
        echo "<div style='color: red; border: 1px solid red; padding: 10px;'>";
        echo "<strong>Błędy:</strong><ul>";
        foreach ($errors as $error) {
            echo "<li>$error</li>";
        }
        echo "</ul></div>";
    } else {
        // Pobierz i zabezpiecz dane
        $imie = htmlspecialchars($_POST['imie'], ENT_QUOTES, 'UTF-8');
        $nazwisko = htmlspecialchars($_POST['nazwisko'], ENT_QUOTES, 'UTF-8');
        
        echo "<p>Witaj $nazwisko $imie na mojej stronie.</p>";
        
        // Zbierz informacje
        $info = "<div style='border: 1px solid #ccc; padding: 15px; margin: 10px 0;'>";
        $info .= "<h3>Przekazane dane:</h3>";
        
        // Wiadomość
        if (!empty($_POST['wiadomosc'])) {
            $wiadomosc = htmlspecialchars($_POST['wiadomosc'], ENT_QUOTES, 'UTF-8');
            $info .= "<p><strong>Wiadomość:</strong><br>" . nl2br($wiadomosc) . "</p>";
        }
        
        // Płeć
        if (!empty($_POST['plec'])) {
            $plec_map = ['k' => 'Kobieta', 'm' => 'Mężczyzna', 'i' => 'Inne'];
            $plec = $plec_map[$_POST['plec']] ?? 'Nieznana';
            $info .= "<p><strong>Płeć:</strong> $plec</p>";
        }
        
        // Gry (checkboxy pojedyncze)
        $gry = [];
        if (!empty($_POST['gra1'])) $gry[] = $_POST['gra1'];
        if (!empty($_POST['gra2'])) $gry[] = $_POST['gra2'];
        if (!empty($_POST['gra3'])) $gry[] = $_POST['gra3'];
        
        if (!empty($gry)) {
            $info .= "<p><strong>Ulubione gry:</strong> " . 
                     implode(', ', array_map('htmlspecialchars', $gry)) . "</p>";
        }
        
        // Jedzenie (checkboxy jako tablica)
        if (!empty($_POST['food']) && is_array($_POST['food'])) {
            $food = array_map('htmlspecialchars', $_POST['food']);
            $info .= "<p><strong>Ulubione jedzenie:</strong> " . 
                     implode(', ', $food) . "</p>";
        }
        
        // Klasa (select)
        if (!empty($_POST['klasa'])) {
            $klasa = htmlspecialchars($_POST['klasa']);
            $info .= "<p><strong>Klasa:</strong> $klasa</p>";
        }
        
        // Hobby (select multiple)
        if (!empty($_POST['hobby']) && is_array($_POST['hobby'])) {
            $hobby = array_map('htmlspecialchars', $_POST['hobby']);
            $info .= "<p><strong>Hobby:</strong> " . 
                     implode(', ', $hobby) . "</p>";
        }
        
        $info .= "<p><em>Data zapisu: " . date('Y-m-d H:i:s') . "</em></p>";
        $info .= "</div>";
        
        echo $info;
        
        // Zapis do pliku
        $file = "dane.txt";
        $f = fopen($file, 'a');
        
        if ($f !== false) {
            flock($f, LOCK_EX);
            fwrite($f, strip_tags($info) . "\n" . str_repeat('-', 80) . "\n");
            fflush($f);
            flock($f, LOCK_UN);
            fclose($f);
            
            echo "<p style='color: green;'>Dane zapisane do pliku!</p>";
        } else {
            echo "<p style='color: red;'>Błąd zapisu do pliku</p>";
        }
    }
}
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Formularz</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
        }
        form {
            background: #f5f5f5;
            padding: 20px;
            border-radius: 5px;
        }
        label {
            display: block;
            margin-top: 10px;
            font-weight: bold;
        }
        input[type="text"],
        textarea,
        select {
            width: 100%;
            padding: 8px;
            margin-top: 5px;
            box-sizing: border-box;
        }
        button {
            margin-top: 20px;
            padding: 10px 20px;
            background: #007bff;
            color: white;
            border: none;
            cursor: pointer;
            font-size: 16px;
        }
        button:hover {
            background: #0056b3;
        }
        .checkbox-group,
        .radio-group {
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <h1>Formularz rejestracyjny</h1>
    
    <form method="POST">
        <label for="nazwisko">Nazwisko: *</label>
        <input type="text" id="nazwisko" name="nazwisko" required>
        
        <label for="imie">Imię: *</label>
        <input type="text" id="imie" name="imie" required>
        
        <label for="wiadomosc">Wiadomość:</label>
        <textarea id="wiadomosc" name="wiadomosc" rows="5"></textarea>
        
        <div class="radio-group">
            <label>Płeć:</label>
            <input type="radio" name="plec" value="k" id="plec_k">
            <label for="plec_k" style="display: inline; font-weight: normal;">Kobieta</label>
            
            <input type="radio" name="plec" value="m" id="plec_m">
            <label for="plec_m" style="display: inline; font-weight: normal;">Mężczyzna</label>
            
            <input type="radio" name="plec" value="i" id="plec_i">
            <label for="plec_i" style="display: inline; font-weight: normal;">Inne</label>
        </div>
        
        <div class="checkbox-group">
            <label>Ulubione gry:</label>
            <input type="checkbox" name="gra1" value="CS" id="gra1">
            <label for="gra1" style="display: inline; font-weight: normal;">CS</label>
            
            <input type="checkbox" name="gra2" value="LOL" id="gra2">
            <label for="gra2" style="display: inline; font-weight: normal;">LOL</label>
            
            <input type="checkbox" name="gra3" value="WOW" id="gra3">
            <label for="gra3" style="display: inline; font-weight: normal;">WOW</label>
        </div>
        
        <div class="checkbox-group">
            <label>Ulubione jedzenie:</label>
            <input type="checkbox" name="food[]" value="pizza" id="food1">
            <label for="food1" style="display: inline; font-weight: normal;">Pizza</label>
            
            <input type="checkbox" name="food[]" value="bigos" id="food2">
            <label for="food2" style="display: inline; font-weight: normal;">Bigos</label>
            
            <input type="checkbox" name="food[]" value="jajecznica" id="food3">
            <label for="food3" style="display: inline; font-weight: normal;">Jajecznica</label>
            
            <input type="checkbox" name="food[]" value="lody" id="food4">
            <label for="food4" style="display: inline; font-weight: normal;">Lody</label>
        </div>
        
        <label for="klasa">Klasa:</label>
        <select name="klasa" id="klasa">
            <option value="">-- Wybierz --</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
        </select>
        
        <label for="hobby">Hobby (przytrzymaj Ctrl aby wybrać wiele):</label>
        <select name="hobby[]" id="hobby" multiple size="4">
            <option value="IT">IT</option>
            <option value="PHP">PHP</option>
            <option value="sport">Sport</option>
            <option value="ryby">Wędkarstwo</option>
        </select>
        
        <button type="submit" name="przycisk">Wyślij</button>
    </form>
    
    <p style="margin-top: 20px;">
        <a href="podglad.php" target="_blank">📄 Podgląd zapisanych danych</a>
    </p>
</body>
</html>

Plik podglad.php

<?php
$file = 'dane.txt';

if (!file_exists($file) || filesize($file) == 0) {
    echo "Brak zapisanych danych.";
    echo "<br><br><a href='formularz.php'>Dodaj dane</a>";
    exit;
}

$zawartosc = file_get_contents($file);
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Podgląd danych</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 900px;
            margin: 50px auto;
            padding: 20px;
        }
        .content {
            background: #f9f9f9;
            padding: 20px;
            border: 1px solid #ddd;
            white-space: pre-wrap;
        }
        .buttons {
            margin-top: 20px;
        }
        a {
            display: inline-block;
            padding: 10px 20px;
            margin-right: 10px;
            background: #007bff;
            color: white;
            text-decoration: none;
            border-radius: 5px;
        }
        a:hover {
            background: #0056b3;
        }
        .delete {
            background: #dc3545;
        }
        .delete:hover {
            background: #c82333;
        }
    </style>
</head>
<body>
    <h1>📄 Zapisane dane</h1>
    
    <div class="content">
        <?= nl2br(htmlspecialchars($zawartosc)) ?>
    </div>
    
    <div class="buttons">
        <a href="formularz.php">➕ Dodaj kolejne dane</a>
        <a href="del.php" class="delete" 
           onclick="return confirm('Czy na pewno usunąć wszystkie dane?')">
            🗑️ Usuń plik
        </a>
    </div>
</body>
</html>

Plik del.php

<?php
$file = 'dane.txt';

if (file_exists($file)) {
    if (unlink($file)) {
        $message = "Plik został usunięty";
        $status = "success";
    } else {
        $message = "Błąd podczas usuwania pliku";
        $status = "error";
    }
} else {
    $message = "Plik nie istnieje";
    $status = "warning";
}
?>

<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Usuwanie pliku</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 50px auto;
            padding: 20px;
            text-align: center;
        }
        .message {
            padding: 20px;
            margin: 20px 0;
            border-radius: 5px;
            font-size: 18px;
        }
        .success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        .error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        .warning {
            background: #fff3cd;
            color: #856404;
            border: 1px solid #ffeeba;
        }
        a {
            display: inline-block;
            margin-top: 20px;
            padding: 10px 20px;
            background: #007bff;
            color: white;
            text-decoration: none;
            border-radius: 5px;
        }
        a:hover {
            background: #0056b3;
        }
    </style>
</head>
<body>
    <div class="message <?= $status ?>">
        <?= $message ?>
    </div>
    
    <a href="formularz.php">Powrót do formularza</a>
</body>
</html>

Przykład – upload plików

Formularz uploadu

<!-- WAŻNE: enctype="multipart/form-data" -->
<form method="POST" enctype="multipart/form-data">
    <label>Wybierz plik:</label>
    <input type="file" name="plik" accept="image/*,application/pdf">
    
    <button type="submit" name="upload">Prześlij</button>
</form>

Obsługa uploadu

<?php
if (isset($_POST['upload']) && isset($_FILES['plik'])) {
    $file = $_FILES['plik'];
    
    // Sprawdź błędy
    if ($file['error'] !== UPLOAD_ERR_OK) {
        echo "Błąd uploadu: " . $file['error'];
        exit;
    }
    
    // Sprawdź rozmiar (5MB max)
    $maxSize = 5 * 1024 * 1024;
    if ($file['size'] > $maxSize) {
        echo "Plik za duży (max 5MB)";
        exit;
    }
    
    // Sprawdź rozszerzenie
    $allowedExt = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    
    if (!in_array($ext, $allowedExt)) {
        echo "Niedozwolone rozszerzenie: $ext";
        exit;
    }
    
    // Utwórz katalog jeśli nie istnieje
    $uploadDir = 'uploads/';
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0755, true);
    }
    
    // Generuj unikalną nazwę
    $newName = uniqid() . '.' . $ext;
    $destination = $uploadDir . $newName;
    
    // Przenieś plik
    if (move_uploaded_file($file['tmp_name'], $destination)) {
        echo "Plik przesłany: $destination";
    } else {
        echo "Błąd przenoszenia pliku";
    }
}
?>

Zadania:

W każdym zadaniu należy sprawdzić, czy dane istnieją. Używaj metody bezpiecznej, chyba że rodzaj zadania wymaga innego podejścia.

Zadanie 1: Stwórz formularz, który na podstawie podanych przez użytkownika ilości kolumn i wierszy, narysuje tabelę w HTMLu. Wypełnij pola tabeli losowymi kolorami.

Zadanie 2: Stwórz formularz, który po kliknięciu przycisku będzie losował liczby totolotka (zakres 1-49), umożliw podanie użytkownikowi ilości zestawów do wygenerowania. (np. wpisuje 3 – więc 3 razy generuje się zestaw itd.).

Zadanie 3: Stwórz formularz, który będzie zawierał listę rzeczy do kupienia. W tabeli wyświetl produkt, ilość i cenę. Produkt ma zawierać checkboxa oraz nazwę; ilość i cena mogą być edytowane (po pierwszym uruchomieniu wypełnione dowolnymi wartościami – ty decydujesz). Zadeklaruj przynajmniej 6 produktów do wyboru. Po wybraniu produktów (zaznaczeniu checkboxów) i wysłaniu formularza wyświetli się paragon, tak jak w sklepie (poszukaj jakiegoś w plecaku i wykorzystaj za wzór).

Zadanie 4: Stwórz grę „papier, kamień, nożyce”. Informację o wyniku przechowuj w zmiennej sesyjnej. Jeżeli nie znasz jeszcze sesji to możesz wynik danego gracza przekazywać w polu ukrytym

np. <input type=”hidden” name=”licznik_player” value=”<?=$licznik_player?>”>

Zadanie 5: Stwórz rozbudowany formularz danych użytkownika w PHP, który umożliwia:

  1. zapisanie wprowadzonych danych do pliku tekstowego,
  2. odczytanie zapisanych danych i ich czytelne wyświetlenie w przeglądarce.

Formularz powinien zawierać m.in.:

Dane osobowe

  • Imię i nazwisko (pole tekstowe)

  • Adres e-mail (pole typu email)

  • Hasło (pole typu password)

  • Numer telefonu (pole typu tel)

  • Data urodzenia (pole typu date)

  • Wiek (pole typu number)

  • Płeć (radio button: mężczyzna / kobieta / inne)

  • Zdjęcie profilowe (upload pliku) – opcjonalne

Dane adresowe

  • Ulica i numer domu

  • Kod pocztowy

  • Miasto

  • Województwo (lista rozwijana select)

  • Kraj (lista rozwijana select)

  • Współrzędne GPS (pole tekstowe)

Dane zawodowe

  • Stanowisko

  • Nazwa firmy

  • Doświadczenie zawodowe (liczba lat)

  • Branża (lista rozwijana z możliwością wyboru kilku opcji – multiple)

  • Przedział wynagrodzenia (range)

Preferencje i zainteresowania

  • Ulubione kolory (color)

  • Ulubione dni tygodnia (checkbox)

  • Ulubiona godzina (time)

  • Ulubiony miesiąc (month)

  • Adres strony internetowej (url)

  • Krótki opis zainteresowań (textarea)

  • Upload pliku CV (file) – opcjonalnie

  • Zgoda na newsletter (checkbox)

  • Ocena poziomu satysfakcji (range)

Inne elementy

  • Pole ukryte (hidden) – np. data wysłania formularza

  • Przycisk wyczyszczenia formularza (reset)

  • Przycisk wysyłania (submit)


Zapis danych do pliku

Po przesłaniu formularza dane użytkownika powinny zostać zapisane do pliku tekstowego (np. dane.txt).
Każdy wiersz w pliku powinien zawierać dane jednego użytkownika, rozdzielone średnikami (;) — np.:

Jan Kowalski;jan.kowalski@example.com;35;mężczyzna;Warszawa;Programista;IT;#3498db;Tak;2025-10-27

Do zapisu możesz wykorzystać funkcje PHP takie jak:

  • fopen(),

  • fputcsv() – poczytaj o tej funkcji w dokumentacji technicznej

  • fclose().


Odczyt danych (dane.php)

Dane powinny wyświetlać się w formie tabeli HTML. Tabela powinna:

  • mieć nagłówki kolumn,

  • prezentować wszystkie zapisane dane użytkowników,

  • wyświetlać komunikat „Brak zapisanych danych”, jeśli plik jest pusty.


Wymagania techniczne

  • Walidacja pól formularza po stronie HTML5 (np. required, min, max, pattern).

  • Dane powinny być zabezpieczone przed wstrzyknięciami HTML (np. za pomocą htmlspecialchars()).

  • Użytkownik po przesłaniu formularza powinien zobaczyć komunikat o poprawnym zapisie danych.

  • Pliki przesyłane przez użytkownika (np. zdjęcie, CV) powinny być zapisywane w katalogu uploads/.