Blok 1 · rozdział 1

Projekt Korona i po co Laravel

Przez te 40 godzin robisz jedną aplikację: Korona Gór Polski. Użytkownik zakłada konto i zapisuje szczyty, na których był. Laravel daje na to gotowe katalogi i polecenia, więc nie zaczynasz każdej strony od pustego pliku PHP.

Blok 1 28 szczytów MVC

Po tym rozdziale powinieneś umieć

  • opisać, co użytkownik robi w gotowej aplikacji;
  • wymienić, które problemy framework rozwiązuje za Ciebie (trasy, widoki, baza, konto);
  • rozpisać otwarcie karty Rysów na trasę, kontroler, model i widok;
  • powiedzieć, czego na tym kursie nie instalujemy: Reacta, Vue i Inertii.

1. Co budujemy

Korona Gór Polski to lista 28 szczytów — po jednym z pasma — opisana w 1997 roku przez Marka Więckowskiego i Wojciecha Lewandowskiego. Najwyższy jest Rysy (2499 m), najniższy na liście kursowej to Łysica (614 m). Kto zbierze wszystkie, „zamyka koronę”.

Aplikacja ma cztery ekrany:

  1. Lista szczytów — nazwa, pasmo, wysokość, od najwyższego.
  2. Karta szczytu — jeden szczyt i formularz „byłem tutaj”.
  3. Konto — rejestracja, logowanie, wylogowanie.
  4. Moja Korona — ile szczytów już masz, np. 6/28, i których brakuje.
Zdobycie W tej aplikacji to rekord: kto, który szczyt, jakiego dnia, z krótką notatką. Jedno zdobycie na parę „użytkownik + szczyt”. Drugi raz tego samego szczytu nie dopisujesz — poprawiasz datę.
Wysokości W przewodnikach te same szczyty różnią się o kilka metrów, bo pomiary GPS są nowsze niż lista z lat 90. Na kursie wszyscy korzystacie z jednej listy, z pliku materialy/korona.php, żeby w grupie były te same rekordy.

2. Framework a własny PHP

W PAI układasz pliki sam: formularz, include, tablica $_POST, czasem PDO i password_hash. Przy drugiej i trzeciej stronie wracają te same kawałki: połączenie z bazą, sprawdzenie logowania, ochrona przed wklejonym HTML-em.

Framework to gotowy szkielet aplikacji. Laravel przynosi katalogi, polecenia php artisan, zapis tras, widoki Blade i dostęp do bazy przez klasy (Eloquent). Nadal piszesz PHP, tylko powtarzalne rzeczy wywołujesz po nazwie, a nie kopiujesz z poprzedniego zadania.

Zadanie Czysty PHP z PAI Na tym kursie
Adres strony Osobny plik, np. szczyt.php?id=3 Trasa w routes/web.php, np. /szczyty/rysy
HTML echo pomieszany z kodem Widok Blade w resources/views
Baza SQL w stringu, PDO Model Eloquent: Szczyt::orderByDesc('wysokosc_m')->get()
Konto Własna sesja i password_hash Breeze generuje rejestrację i logowanie (blok 4)
Szukanie bez przeładowania całej strony Własny JavaScript Livewire: logika zostaje w PHP (blok 5)
Bez Reacta i Vue Instalator Laravela proponuje gotowe startery w React, Vue albo Livewire z biblioteką Flux. Tych starterów nie bierzemy, bo na początku mają być widoczne trasy, kontrolery i Blade. Breeze z widokami Blade dojdzie w bloku 4. W bloku 5 dołożysz jeden komponent Livewire.

3. MVC w Laravelu

MVC dzieli aplikację na trzy części: model, widok i kontroler. W Laravelu przed nimi jest jeszcze trasa. Do skrótu jej nie wliczamy. Trasa wskazuje tylko, która metoda kontrolera obsłuży dany adres.

Model Trzyma dane. Klasa Szczyt czyta wiersz z tabeli i wie, do jakiego pasma należy. Nie składa strony i nie sprawdza, jaki adres wpisał użytkownik.
Widok Plik Blade, czyli HTML z miejscami na dane. Dostaje je od kontrolera i wypisuje. Nie zapisuje zdobycia w bazie i nie sprawdza hasła.
Kontroler Decyduje przy jednym adresie: co pobrać, czy wolno, który widok odesłać albo dokąd przekierować. Nie jest szablonem strony i nie trzyma tabel w MySQL.

Jedno otwarcie karty, krok po kroku

Użytkownik klika „Rysy”. Przeglądarka wysyła żądanie GET /szczyty/rysy. Dalej dzieje się to po stronie serwera, zanim cokolwiek wróci na ekran.

  1. Trasa. Laravel czyta routes/web.php i szuka wpisu na GET /szczyty/{szczyt}. Znajduje wskazanie: klasa SzczytController, metoda show.
  2. Kontroler. Metoda show dostaje fragment adresu rysy. Nie skleja SQL-a w widoku. Prosi model o ten jeden szczyt.
  3. Model. Klasa Szczyt czyta z MySQL wiersz, którego slug to rysy, razem z pasmem (Tatry) i wysokością. Gdy wiersza nie ma, Laravel kończy kodem 404. Do przeglądarki nie idzie pusta karta.
  4. Kontroler jeszcze raz. Dostaje obiekt szczytu i wybiera widok szczyty.show. Przekazuje mu ten obiekt. Sam nie pisze nagłówków HTML.
  5. Widok Blade. Wstawia nazwę, pasmo i wysokość w miejsca {{ }}. Laravel zamienia plik Blade na HTML.
  6. Przeglądarka. Dostaje gotową stronę. W źródle widać HTML. Nie widać klasy Szczyt, treści .env ani zapytania do bazy.

Podział obowiązków

TrasaKontrolerModelWidok
Wie o adresie tak dostaje go od trasy nie nie
Czyta i zapisuje wiersze nie prosi o to model tak nie
Składa HTML nie wybiera plik widoku nie tak
Plik w projekcie routes/web.php app/Http/Controllers app/Models resources/views

To samo przy zapisie zdobycia

Klik „Zapisz zdobycie” wysyła inne żądanie: POST /szczyty/rysy/zdobycia. Trasa wskazuje inną metodę. Kontroler sprawdza datę i to, czy użytkownik jest zalogowany. Model dopisuje wiersz w tabeli zdobycia. Pole user_id bierze z sesji, a nie z ukrytego pola formularza. Po udanym zapisie kontroler przekierowuje na kartę szczytu, a widok pokazuje komunikat „zapisano”.

W bloku 1 modelu jeszcze nie ma

W rozdziałach 3–6 lista szczytów jest jeszcze zwykłą tablicą PHP. Trasa i widok działają tak samo jak później. Od bloku 2 między trasą a widokiem staje kontroler. Od bloku 3 tablicę zastępuje model Szczyt i tabela w MySQL. Widok czyta wtedy $szczyt->nazwa, a nie $szczyt['nazwa']. Wysokość poprawiasz w bazie. W pliku Blade jej już nie zmieniasz.

Warto zapamiętać Przeglądarka prosi o adres, trasa wybiera metodę kontrolera, kontroler bierze dane z modelu i oddaje widok. W źródle strony widać HTML. Klasy PHP tam nie ma.

4. Pięć bloków

BlokCo robiszSkąd bierze się lista szczytów
1Instalacja, trasy, Bladetablicy PHP w kodzie
2Kontroler, układ, komponent, formularztej samej tablicy, już przez kontroler
3Migracje, modele, seederbazy MySQL
4Breeze i zdobyciabazy; zapis jest przypisany do konta
5Livewire i domknięciebazy; szukanie bez nowego pliku JS

Tablica z bloku 1 jest tymczasowa. W bloku 3 ją usuwasz. Jeśli zostawisz i tablicę, i bazę, poprawisz wysokość w phpMyAdmin, a strona i tak pokaże starą wartość z kodu.

5. Dane, które zapiszemy

pasma

Nazwa, np. Tatry. Jeden wiersz na pasmo.

1 : N

szczyty

Nazwa, slug, wysokość. Klucz obcy do pasma.

users

Konto z Breeze: imię, e-mail, hasło.

N : M
przez zdobycia

szczyty

Ten sam szczyt może mieć wielu zdobywców.

Tabela zdobycia trzyma datę i notatkę, więc to nie jest pusta tabela łącząca. Znasz ten układ z BD: związek wiele-do-wielu z własnymi atrybutami.