Wprowadzanie danych z formularza HTML do bazy MySQLi
Zadanie 151: Wprowadzanie danych z formularza HTML do bazy MySQLi
Wstęp
W poprzednim zadaniu dowiedzieliśmy się, jak pobierać i wyświetlać dane z bazy MySQL. Kolejnym naturalnym krokiem w budowie dynamicznych aplikacji webowych jest umożliwienie użytkownikom wprowadzania i zapisywania własnych informacji. Najczęściej realizuje się to za pomocą interaktywnych formularzy HTML oraz języka PHP, który odbiera przekazane dane i za pomocą instrukcji INSERT rejestruje je na stałe w tabeli.
Cel zadania
Nauczysz się, w jaki sposób zintegrować formularz HTML obsługujący dane wprowadzane przez użytkownika ze skryptem PHP, który odbierze te wartości i przy użyciu ulepszonej klasy mysqli wstawi bezpiecznie nowy dokument prosto do bazy danych.
Wymagania techniczne
- Wykorzystać istniejącą tabelę
pracownicy(wygenerowaną w Zadaniu 150). - Stworzyć widok z formularzem HTML z polami wejściowymi odpowiadającymi polom w tabeli (imię, nazwisko, stanowisko, pensja).
- Napisać funkcjonalność w PHP używającą tablicy globanej
$_POST, by odebrać wysłane argumenty. - Wykorzystać niezbędne mechanizmy w celu "oczyszczenia" danych do zabezpieczeń.
- Wysłać i sfinalizować zapytanie
INSERT INTO, co pozwoli rozszerzyć bazę o wpis użytkownika.
Kroki do wykonania
1. Przygotowanie formularza HTML
Aby użytkownik zapisał informacje z klawiatury, potrzebujemy udostępnić odpowiednie pola wejściowe (np. elementy domyślne input typu wariantowego text oraz liczbowego number). Formularz musi zostać skonfigurowany, by wysyłał zapytanie przy pomocy bezpieczniejszej przesyłki czyli POST. Mamy wtedy pewność, że atrybuty nie będą uwidocznione i ograniczane przez wiersz nagłówkowy adresu URL.
<!-- Przykład zarysu strukturalnego formularza -->
<h2>Dodaj nowego pracownika</h2>
<form action="" method="POST">
<label for="imie">Imię:</label><br>
<input type="text" id="imie" name="imie" required><br><br>
<label for="nazwisko">Nazwisko:</label><br>
<input type="text" id="nazwisko" name="nazwisko" required><br><br>
<label for="stanowisko">Stanowisko:</label><br>
<input type="text" id="stanowisko" name="stanowisko" required><br><br>
<label for="pensja">Pensja (PLN):</label><br>
<input type="number" step="0.01" id="pensja" name="pensja" required><br><br>
<input type="submit" value="Dodaj pracownika">
</form>
2. Odbiór danych w PHP i podstawowe zabezpieczenia
Gdy wciśnięty zostanie główny guzik ("submit"), wpisane polecenia trafią do zaprogramowanej fabrycznie tablicy $_POST. Zadbanie o poprawny odbiór zaczyna się jednak uprzednio od zagwarantowania otwarcia obwodu bazy. Pusty ciąg nie przejdzie, natomiast zabezpieczenie przez mysqli_real_escape_string uchroni parser przed ewentualną modyfikacją składni np. podatnością SQL Injection.
<?php
// Połączenie z naszą testową bazą
$conn = mysqli_connect("localhost", "root", "", "firma");
if (!$conn) {
die("Błąd połączenia: " . mysqli_connect_error());
}
mysqli_set_charset($conn, "utf8");
// Sprawdzenie, czy formularz metodą POST odesłał informacje z front-endu
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Oczyszczanie poszczególnych zmiennych
$imie = mysqli_real_escape_string($conn, $_POST['imie']);
$nazwisko = mysqli_real_escape_string($conn, $_POST['nazwisko']);
$stanowisko = mysqli_real_escape_string($conn, $_POST['stanowisko']);
// Pensję, jako jednostkę numeryczną deklarujemy jawnie na typ Float eliminując znaki alfabetyczne
$pensja = (float) $_POST['pensja'];
// Wszystkie dane zakodowane w dedykowanych zmiennych czekają na utworzenie zapytania
}
?>
3. Zapisanie danych w bazie (INSERT)
Gdy pozbyliśmy się niebezpiecznych wyjątków możemy kontynuować, wykorzystując komendę INSERT. Czysto numeryczne wejścia zapisujemy wprawdzie od razu, po łańcuchy ujęte w zmiennych należy przekładać po użyciu ujęć cudzysłowów pojedynczych apostrofów SQL-a.
<?php
// Ciąg dalszy kodu, gdzie deklarujemy zapytanie dodające wiersz na koniec tabeli
$sql = "INSERT INTO pracownicy (imie, nazwisko, stanowisko, pensja)
VALUES ('$imie', '$nazwisko', '$stanowisko', $pensja)";
// Przeprowadzenie funkcji query ułoży nowe polecenie w serwer
if (mysqli_query($conn, $sql)) {
echo "<p>Nowy pracownik został poprawnie dodany w strukturach bazy!</p>";
} else {
echo "<p>Błąd w logowaniu rekordu: " . mysqli_error($conn) . "</p>";
}
// Obowiązkowe zamknięcie zestawienia
mysqli_close($conn);
?>
[!WARNING] W bardzo skomplikowanych frameworkach lub profesjonalnych aplikacjach, wykorzystuje się standard z zapytań przygotowanych zwanych jako "Prepared Statements" oraz funkcje
mysqli_prepare,mysqli_stmt_bind_param. Mają one na celu definitywne oddzielenie zmiennych logiki od głównego kodu SQL - nasza funkcja escape'ującamysqli_real_escape_stringpomimo wieku również działa zapobiegawczo dla ataków ale przygotowane instrukcje dają lepszą widoczność kodu!
Zadania dla chętnych
Poniżej znajdziesz 5 dodatkowych wytycznych do modyfikacji powyższego skryptu. Postaraj się je samodzielnie wdrożyć do przygotowanego pliku, pamiętając, że nie masz udostępnionych ich odgórnych rozwiązań:
- Walidacja danych po stronie serwera: Zabezpieczenie nałożone po stronie weryfikacji formularza (atrybuty
required) może zostać w prosty sposób usunięte w opcjach deweloperskich przeglądarki. Zaimplementuj kod oparty na warunku (np. z funkcjąempty()), aby przed wykonaniem odpytania SQL przetestować, czy przesyłane Imie oraz Nazwisko na pewno nie opiewają pustką, inaczej wyświetl błąd. - Minimalna długość nazwiska: Dołóż przed zapytaniem dodatkowy algorytm testacyjny odwołujący się do zliczania wymiarów parametrów String, przez wbudowaną komendę
strlen(). Odmów rejestracji dokumentu w przypadku stwierdzenia, że nazwisko zajmuje mniej niż 3 ustandaryzowane znaki wymuszając rozszerzenie podanego słowa we własnym komunikacie. - Zapobieganie dodawaniu powtórek wejściowych: Czasami z powodu błędnego odesłania formularza dwa razy kliknięto ten sam guzik. Stwórz skrypt prewencyjnie pobierający informację (
SELECT), aby uprzednim zliczeniem z weryfikacją zablokować i nie zatwierdzać osoby zgłaszającej nowe dane, w sytuacji gdzie pokrywa się identycznie ona ze znakami imienia oraz nowostwórcami obecnymi w kolumnie "Nazwisko" z tabeli. - Rozszerzenie formularza o sposób rozliczenia pensji: Nadaj formularzowi kontrolkę elementu
<select>, umożliwiającą wyłonienie preferencji typu wypłacanego ryczałtu (brutto lub netto). Wykorzystując to pole oblicz stawkę procentową odpowiednią dla warunków netto z narzuconym modelem rzucanego podatku, redefiniując główną zmienną i ostatecznie przetrzymując do nowej bazy tylko kwoty uregulowane. - Przekierowanie po udanej operacji do widoku wierszy: Połącz operacje wykonywane w poprzednim Zasadami nr 150 – z wyświetlanym widokiem w jednym dużym głównym serwisie firmowym z listą pod którą wyświetla sie pole na nowe edytowania pracownicze. Jeśli komenda zakończy wprowadzanie na stronie pozytywnie w warunku
if (mysqli_query..., sprowokuj wyczyszczające zapętlony kod polecenie globalneheader("Location: twoja_strona_glowna.php");ładując stronę od nowa tym samym eliminując szansę omyłkowego zdublowania wpisu i ujawniając rezultat wprowadzony u góry ekranu.