Tworzymy prosty formularz HTML i widok formularza
Aby rozpocząć przygotuję prosty formularz HTML, bez dodatkowej stylizacji, ponieważ stylami i zaawansowanymi widokami mam zamiar zając się w kolejnych części szkolenia. Zakładając, iż czytelnik zapoznał się z poprzednimi częściami szkolenia i wykonał opisanie w nich czynności, takie jak migracje i wprowadzanie szkoleniowych danych do tabeli, niniejsza część szkolenia stanowi kontynuację poprzednich części. Stworzę więc prosty formularz, poprzez który będzie można wprowadzać nowe posty do tabeli bazy danych.
Nasz szkoleniowy formularz HTML, zachowany w pliku
resources/views/posts/nowy.blade.php
względem katalogu głównego naszej szkoleniowej aplikacji, może wyglądać następująco:
<html>
<head></head>
<body>
<form method="POST" action=" {{asset('/posty')}} ">
{{ csrf_field() }}
<div>
<label for="title">Tytuł:</label>
<input type="text" id="title" name="title">
</div>
<br />
<div>
<label for="body">Treść:</label>
<textarea id="body" name="body"></textarea>
</div>
<br />
<div>
<button type="submit">Zapisz</button>
</div>
</form>
</body>
<head></head>
<body>
<form method="POST" action=" {{asset('/posty')}} ">
{{ csrf_field() }}
<div>
<label for="title">Tytuł:</label>
<input type="text" id="title" name="title">
</div>
<br />
<div>
<label for="body">Treść:</label>
<textarea id="body" name="body"></textarea>
</div>
<br />
<div>
<button type="submit">Zapisz</button>
</div>
</form>
</body>
Są dwa aspekty powyższego formularza, na które należy zwrócić szczególną uwagę, ponieważ są one związane ściśle ze środowiskiem Laravel.
Pole CSRF
Laravel ułatwia ochronę aplikacji przed atakami polegającymi na fałszowaniu żądań między witrynami (CSRF). Ataki typu "cross-site request" są rodzajem złośliwego exploita polegającego na wykonywaniu nieautoryzowanych poleceń w imieniu uwierzytelnionego użytkownika.
Funkcja csrf_field() wywołana w formularzu, ma za zadanie wstawić do formularza ukryte pole z wartością, która po wysłaniu formularza będzie porównywana z wartością zachowaną w specjalnie stworzoznej w celach kontrolnych zmiennej sesyjnej. Możemy podejrzeć źródło strony formularza, a wówczas zobaczymy, iż w formularzu widnieje element ukrytego pola z wartością w postaci długiego ciągu znaków. Jeśli do naszego formularza nie dodamy tej funkcji, wysłanie go nie będzie możliwe.
Akcja formularza
Jak zapewne czytelnicy dobrze wiedzą, atrybut action określa w formularzu HTML adres url, na który ma zostać wysłane żądanie HTTP formularza. W naszym przypadku będzie to żądanie typu POST, skierowane do adresu określonego przez funkcję asset(), która zwróci bezwzględny adres URL na podstawie określonego w niech adresu względnego '/posty'.
Po utworzeniu pliku formularza, musimy się zająć utworzeniem widoku. W tym celu do naszego pliku
routes/web.php
dodajemy wpis, kierujący żądanie HTTP typu GET adresu względnego posty/nowy do funkcji create() naszego kontrolera zasobów PostController:
Route::get('/posty/nowy', 'PostController@create');
Następnie w klasie naszego kontrolera zasobów PostController tworzymy metodę create(), wyświetlającą formularz, czyli zwracającą utworzony widok formularza:
public function create() {
return view('posts.create');
}
return view('posts.create');
}
Jeśli wszystkie czynności zostały wykonane zgodnie ze wskazówkami, po przejściu na względny adres url /posty/nowy naszej szkoleniowej aplikacji, w przeglądarce powinien się pojawić nasz szkoleniowy formularz html.
Szkoleniowa wersja przykładowego formularza hrml |
Efekt działania funkcji csrf() |
Tworzymy nową trasę
Formularz jest już widoczny, lecz musimy utworzyć trasę dla akcji formularza, czyli przypisaną do żądania typu POST na adres /posty. W tym celu wystarczy dodać do naszego szkoleniowego pliku routes/web następującą zawartość, która będzie miała za zadanie przekierowywać takie żądanie do funkcji store() kontrolera PostController, której strukturę za chwilę przedstawię:
Route::post('/posty', 'PostController@store');
Tworzymy metodę store() w klasie kontrolera zasobów
Nasza metoda o nazwie store() będzie miala za zadanie wykonywać walidację formularza, a następnie zachowywać nowe posty w tabeli bazy danych. Kod naszej szkoleniowej funkcji jest bardzo krótki i przejrzysty:
public function store() {
// Podstawowa walidacja formularza
$this->validate(request(), [
'title' => 'required|min:3|max:60',
'body' => 'required|min:20|max:5000'
]);
// Zachowuje nowy post, utwrzozony z pól title oraz body przesłanego formularza:
Post::create(request(['title', 'body']));
/**
* Alternatywnie, zamiast create()
* $post = new Post(request(['title', 'body']));
* $post->save();
*/
// Przekierowanie do /posty
return redirect('/posty');
// Podstawowa walidacja formularza
$this->validate(request(), [
'title' => 'required|min:3|max:60',
'body' => 'required|min:20|max:5000'
]);
// Zachowuje nowy post, utwrzozony z pól title oraz body przesłanego formularza:
Post::create(request(['title', 'body']));
/**
* Alternatywnie, zamiast create()
* $post = new Post(request(['title', 'body']));
* $post->save();
*/
// Przekierowanie do /posty
return redirect('/posty');
Metoda validate(), służaca do walidacji danych formularza, jest dostępna z poziomu klasy naszego kontrolera i może przyjmować różne reguły. Więcej na temat dostępnych reguł walidacji formularzy można przeczytać w oficjalnej dokumentacji Laravel
Metoda create() tworzy nowy post z zapodanej kolekcji danych i zapisuje go w tabeli bazy danych.
Jednak to nie wszystko. Laravel chroni naszą aplikację przed atakami nie tylko opisaną wyżej funkcją csrf_field(), ale także w dodatkowy sposób. Aby dane z formularza zostały zachowane w bazie danych, należy określić w klasie naszego modelu, jakie dane mogą być modyfikowane przez użytkowników. A więc, aby nasz formularz i przygotowane funkcje zadziałały, wewnątrz klasy modelu Post, czyli w pliku app/Post.php należy dodać:
protected $fillable = ['title', 'body'];
Teraz wszystko powinno już działać. Sprawdźmy to:
Nasz szkoleniowy formularz HTML |
Nasza szkoleniowa dynamiczna lista postów |
Błędy walidacji
Gdy korzystamy z metody validate() wewnątrz klas kontrolerów zasobów, zwraca ona ewentualne błędy walidacyjne do specjalnej zmiennej sesyjnej, która jest dostępna w skryptach formularzy w postaci tablicy $errors. Zobaczmy jak to działa w praktyce, dodając do naszego formularza kilka linijek kodu tuż po znaczniku końca formularza:
<ul>
@foreach ($errors->all() as $error)
<li>{{$error}}</li>
@endforeach
</ul>
@foreach ($errors->all() as $error)
<li>{{$error}}</li>
@endforeach
</ul>
Następnie, mając na uwadze reguły walidacyjne spróbujmy wpisać do pól formularza po jednym znaku, a nstępnie wysłać formularz:
Testujemy walidację |
Błędy walidacyjne |
Informacje o błędach są w języku angielskich, ale tym zajmiemy się w kolejnych częściach szkolenia, jak również ładnie sformatowanymi formularzami, złożonymi widokami oraz stylami CSS.
Serdecznie zapraszam do kolejnej części szkolenia Laravel od podstaw, p.t. Szablony widoków i style CSS
cześć, mam problem z laravelem. Aktualna wersja to 5.6.5, chciałem zainstalować sobie collectiva z formularzami, ale nie chce pójść czy to jest tak że ta wersja jest po prostu nowsza i na nią jeszcze nie wydano?
OdpowiedzUsuńBardzo cenny wpis na blogu. Podoba mi się w jaki sposób uwzględnia on zjawisko jakim jest kontrola procesu produkcyjnego. Rzadko kiedy ktoś zwraca na nie tak intensywną uwagę.
OdpowiedzUsuń