Etykiety

linux (14) php (14) Laravel (9) mysql (9) Hardware (8) Windows (6) sieci (5) PowerShell (4) software (4) MariaDB (3) apache (3) html (3) Microsoft (2) bezpieczeństwo LAN (2) cygwin (2) Akcesoria (1) CMS (1) Laptop (1) Open Office (1) drupal 7 (1) gpg (1) hosting (1) jquery (1) sieci LAN (1) xml (1) zabezpieczenie sieci LAN (1)

czwartek, 30 listopada 2017

Laravel od podstaw: zapis danych z formularza

W poprzedniej części szkolenia, pt. Kontrolery zasobów przedstawiłem ogólny zarys kontrolerów zasobów oraz opisałem korzyści płynące z ich stosowania w środowisku Laravel. W tej części skupię się na opisie przykładowej procedury zachowania w tabeli bazy danych informacji wprowadzanych do formularza.

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>

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');

   }

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 html
Szkoleniowa wersja przykładowego formularza hrml

Wyświetlając źródło strony, warto przyjrzeć się efektom funkcji csrf_field(). Pole typu hidden oraz przypisana do niego wartość pojawiły się w efekcie zastosowania tej funkcji w kodzie.

Efekt działania funkcji csrf()
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');

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
Nasz szkoleniowy formularz HTML


Nasza szkoleniowa dynamiczna lista postów
Nasza szkoleniowa dynamiczna lista postów

Wszystko wygląda tak jak powinno, oczywiście w wersji szkoleniowej, a nie produkcyjnej. Ale co z ewentualnymi błędami walidacyjnymi?

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>

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ę
Testujemy walidację


Błędy walidacyjne
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

2 komentarze:

  1. 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ń
  2. 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ń

Dodaj komentarz