Walidacja danych przesyłanych przez formularze jest jedną z podstawowych funkcji każdej aplikacji. Laravel daje nam do dyspozycji rozbudowany mechanizm walidacji, którego możemy używać na kilka różnych spososób. Począwszy od metody validate()
dostępnej w klasie Request
, przez użycie klas FormRequest
skończywszy na użyciu fasady Validator
i jej metody make()
.
W tym wpisie skupimy się na pierwszym rozwiązaniu, czyli użyciu metody validate()
klasy Request
. Zdefiniujmy dwie ścieżki:
// routes/web.php
Route::get('posts/create', 'PostController@create');
Route::post('posts', 'PostController@store');
Pierwsza ścieżka będzie wyświetlać formularz dodawania wpisu. Druga będzie odpowiedzialna za zapis tego wpisu w bazie danych.
Walidacja danych formularza
Dodajmy kontroler, który będzie obsługiwał powyższe ścieżki:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function create()
{
return view('post.create');
}
public function store(Request $request)
{
$request->validate([
'title' => 'required|min:3|max:255|unique:posts',
'body' => 'required',
]);
// Wpis jest w porządku, możemy go zapisać do bazy danych
}
}
Metoda create()
zwraca tylko widok z formularzem dodawania wpisu. Walidacja ma miejsce w metodzie store()
. Używamy metody validate()
dostępnej w klasie Request
. Metoda ta sprawdza dane przesłane w formularzu. Jeśli dane te spełniają zdefiniowane przez nas reguły walidacji to metoda zakończy działanie bez błędu i zostanie wykonany kod w nastepnych linijkach. Jeśli natomiast dane z formularza nie spełnią reguł walidacji, metoda validate()
wyrzuci wyjątek ValidationException
. Wyjątek ten zostanie przechwycony przez klasę App\Exceptions\Handler
i zamieniony na adekwatną odpowiedź. W przypadku zwykłego zapytania HTTP, będzie to przekierowanie z powrotem do strony formularza z listą błędów walidacji i oryginalnymi danymi formularza zachowanymi w sesji. W przypadku zapytania AJAX będzie to odpowiedź JSON zawierająca błędy walidacji.
Reguły walidacji definiujemy osobno dla każdego pola formularza, oddzielając je znakiem |
. Możemy je także przekazać w formie tablicy:
$request->validate([
'title' => ['required', 'min:3', 'max:255', 'unique:posts'],
'body' => ['required'],
]);
W powyższym przykładzie używamy następujących reguł:
-
required
- pole musi się znajdować w formularzu i wartość pola musi być niepusta -
min
- wartość w polu musi mieć nie mniej niż 3 znaki -
max
- wartość w polu musi mieć nie więcej niż 255 znaków -
unique:posts
- wartość w polu nie może już istnieć w bazie danych w tabeliposts
w kolumnie o nazwie takiej samej jak nazwa pola formularza. W powyższym przykładzie byłaby to kolumnatitle
. Nazwę kolumny można zmienić wskazując ją jako kolejny parametr, na przykład:unique:posts,name
Lista wszystkich dostępnych reguł wraz z opisem działania znajduje się w dokumentacji. Kilka wartch wymienienia, oprócz wspomnianych powyżej, to: alpha
, integer
, date
, email
czy exists
.
Wyświetlanie błędów walidacji
Jak już dowiedzieliśmy się wcześniej, jeśli reguły walidacji nie zostaną spełnione Laravel przekieruje użytkownika z powrotem na stronę formularza. Błędy walidacji zostaną przekazane w sesji. Będziemy mieli do nich dostęp w widoku za pomocą zmiennej $errors
. Użyjmy zatem tej zmiennej do wyświetlenia pod formularzem listy błędów:
// resources/views/posts/create.blade.php
<form action="/posts" method="POST">
@csrf
<input type="text" name="title">
<textarea name="body"></textarea>
<input type="submit" value="Zapisz">
</form>
@if ($errors->any())
<div style="color: red;">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
Zmienna $errors
jest obiektem klasy Illuminate\Support\MessageBag
, która udostępnia kilka wygodnych metod do wyświetlania błędów walidacji. W powyższym kodzie używamy metody any()
, która zwraca informację czy istnieją jakiekolwiek błędy. Następnie używamy metody all()
, która zwraca wszystkie błędy w formie tablicy.
Gdybyśmy zamiast listy błędów pod formularzem chcieli wyświetlić błędy walidacji bezpośrednio pod polem, z którym są związane możemy użyć metod has()
oraz first()
:
<input type="text" name="title">
@if ($errors->has('title'))
<div style="color: red;">
{{ $errors->first('title') }}
</div>
@endif
Metoda has()
sprawdza czy istnieją błędy dla danego pola. Metoda first()
zwraca pierwszy błąd dla danego pola. Począwszy od Laravela w wersji 5.8 możemy też użyć dyrektywy @error
:
@error('title')
<div style="color: red;">{{ $message }}</div>
@enderror
Co ważne, zmienna $errors
jest zawsze dostępna, w każdym widoku. Nawet jeśli jest pusta. Dlatego nie musimy sprawdzać jej istnienia za pomocą funkcji isset()
.
Uzupełnienie pól formularza przesłanymi danymi
Gdy reguły walidacji nie zostaną spełnione Laravel przed przekierowaniem z powrotem na stronę formularza, oprócz umieszczania w sesji błędów walidacji, umieszcza w niej też oryginalne przesłane przez użytkownika dane. To pozwala nam uzupełnić pola formularza danymi wpisanymi wcześniej przez użytkownika. W ten sposób użytkownik musi poprawić tylko zawartość pól, które nie przeszły walidacji, zamiast wpisywać wszystkie pola od nowa. W celu uzupełnienia pól używamy funkcji globalnej old()
:
<input type="text" name="title" value="{{ old('title') }}">
<textarea name="body">{{ old('body') }}</textarea>
W tej części tutoriala dowiedzieliśmy się jak walidować dane przesyłane w formularzach, jak wyświetlać błędy walidacji oraz jak uzupełniać pola formularza przesłanymi wcześniej przez użytkownika danymi. W następnej części nauczymy się uwierzytelniać użytkowników.