[3 z 5] Laravel PHP: Piszemy

Piszemy pierwszy kontroler w Laravelu

W poprzedniej lekcji stworzyliśmy widok wraz z routingiem, by móc nawigować między stronami i w zależności od podanego URL wyświetlić odpowiednią stronę.

Teraz czas nauczyć się pisać własne kontrolery.

Docelowo, przy pomocy kontrolera będziesz przekazywał dane do widoku oraz współpracował z modelem.

Zatem dość pisania, przejdźmy do rzeczy.

Tworzymy nowy kontroler

Co najciekawsze w Laravelu, nie będziemy ręcznie dodawać pliku, zmieniać jego nazwy i wpisywać podstawowej struktury. Skorzystamy z konsolowego narzędzia php artisan, o którym wspominałem już w poprzednich wpisach.

Uruchom konsolę, ustaw się na folderze z aplikacją (w moim przypadku jest to C:\php-source\blog) i wykonaj następującą instrukcję:

C:\php-source\blog> php artisan make:controller ArticleController

W rezultacie otrzymasz informację, że Controller created successfully.

Zajrzyj teraz do swojego projektu i przeglądnij folder app\Http\Controllers. Powinieneś w nim zauważyć plik o nazwie ArticleController.php.

Jest to plik utworzony przez Laravela, który posiada podstawową strukturę kontrolera.

Otwórz go teraz i zobacz zawartość:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleController extends Controller
{
    //
}

Mamy już ustawiony odpowiedni namespace, mamy stworzoną klasę, która rozszerza klasę bazową Controller.

Napiszmy teraz metodę, którą powiążemy z odpowiednim adresem w routingu.

Najpierw, w pliku ArticleController dopisz metodę index, która zwróci widok stworzony przez nas w poprzedniej lekcji. Widok nazywa się hello.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index()
    {
        return view("hello");
    }
}

Następnie w pliku routes\web.php, gdzie trzymamy adresację zasobów, dodaj nową linijkę:

Route::get('/hello2', 'ArticleController@index');

Tym sposobem nauczyłeś swój program, że wpisując adres /hello2 ma uruchomić metodę index w kontrolerze ArticleController.

Gratulacje!

Stworzyłeś już własny widok, własny kontroler oraz skonfigurowałeś dodatkową ścieżkę w routingu. Spróbujmy teraz tak przebudować kontroler wraz z widokiem, by przekazać z niego treść powitania dla użytkownika.

Parametryzujemy widok w Laravelu

Musimy nauczyć widok, jakie parametry otrzyma z kontrolera oraz gdzie i jak ma je wyświetlić. Otwórz plik widoku views\hello.blade.php oraz dopisz jedną linijkę poniżej nagłówka h1:

<h2>{{ $hello }}</h2>

Poznajesz zapewne podwójne nawiasy klamrowe (tzw. łezki), używane przez nas już kilkukrotnie w poprzednich ćwiczeniach. Taki zapis oznacza, że w miejsce $hello chcemy wstawić wartość tej zmiennej. Tym sposobem, przekazując w kontrolerze zmienną $hello o wartości „Witaj na stronie”, otrzymamy wynikowy kod HTML w postaci: <h2>Witaj na stronie</h2>.

Kompletny widok hello.blade.php wygląda teraz tak:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Hello wordpress-438575-1374540.cloudwaysapps.com</title>
    </head>
    <body>
        <h1>Hello world wordpress-438575-1374540.cloudwaysapps.com</h1>
        <h2>{{ $hello }}</h2>
        <p>
            <a href="{{ url('/') }}">Wróć na główną</a>
        </p>
    </body>
</html>

Przekazywanie danych do widoku

Ostatnim krokiem jest uzupełnienie kontrolera o przekazywanie parametru $hello.

Otwórz ponownie plik ArticleController.php z folderu app\Http\Controllers i dopisz przy zwracaniu widoku:

return view("hello")->with("hello", "Witaj na stronie!");

Metoda with (z ang. „wraz z”) oznacza tyle, że chcę dołączyć do zwracanego widoku zmienne wraz z wartościami. Zauważ, że w tej metodzie podajemy nazwy zmiennych w postaci ciągu znaków -> stąd „hello” będzie rozumiane w widoku jako $hello.

Przetestujmy, czy nasze dzieło w ogóle działa.

Wpisuję w konsoli:

C:\php-source\blog> php artisan serve --port 8001
Laravel development server started: <http://127.0.0.1:8001>

Serwer uruchomiony, wchodzę na adres 127.0.0.1:8001/hello2, po czym otrzymuję piękny komunikat powitalny, skonfigurowany w widoku:

Rezultat parametru z kontrolera do widokuPozostaje nam poprawić ostatnią rzecz, gdyż wchodząc na stronę główną i klikając na link hello, dostajemy błąd.

Dzieje się tak, ponieważ link prowadzi jeszcze bezpośrednio do widoku, z pominięciem kontrolera. W widoku nie mamy zmiennej $hello, którą ten widok stara się znaleźć i wyświetlić. Efektem tego jest ekran:

Błąd w Laravelu widok bez zmiennej

Dla programistów PHP ten widok może wydawać się niecodzienny. Przecież do tej pory, gdy nie mieliśmy zdefiniowanej zmiennej, system po prostu wstawiał tam Nulla, a program wykonywał się dalej.

Tutaj mamy nieco większą kontrolę nad tym, co się dzieje. Widoki w Laravelu są bardziej restrykcyjne jeśli chodzi o poprawność danych.

Możemy naprawić ten błąd na dwa sposoby -> albo jawnie określić, że zmienna może nie istnieć (wtedy Laravel ją zignoruje zamiast rzucać błędem) albo przypisać do linku HELLO na stronie głównej odniesienie do kontrolera, zamiast bezpośrednio do widoku.

Sprawdzanie, czy zmienna jest przekazana do widoku

By sprawdzić, czy mamy dostępną daną zmienną, możemy użyć instrukcji @isset bezpośrednio w widoku.

Dodaj następujące sprawdzenie:

@isset($hello)
    <h2>{{ $hello}}</h2>
@endisset

Tym sposobem, jeśli nie przekażesz zmiennej do widoku, całe wyświetlenie nagłówka zostanie pominięte.

Zmiana linku na stronie głównej

Niezależnie od tego, czy wprowadziłeś poprzednią poprawkę, poprawmy link, by korzystał już tylko z kontrolera.

Wyedytuj plik routes\web.php, by odnośnik /hello wskazywał na kontroler ArticleController, a bezpośrednie wyświetlenie widoku całkiem wyleciało.

Finalnie, powinieneś dostać taki efekt:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/hello', 'ArticleController@index');

Tak oto dobrnęliśmy do końca zabawy z pierwszym kontrolerem.

Podsumowanie

Kontroler jest punktem styku między widokiem a modelem.

W praktyce rzadko bywa tak, że widoki są przekazywane bezpośrednio w routes z pominięciem kontrolera. Zazwyczaj, przed zwróceniem widoku, chcesz wykonać jakieś dodatkowe akcje (jak sprawdzenie sesji użytkowika, zalogowanie danej akcji, zebranie danych statystycznych itp.).

Metoda w kontrolerze jest idealnym miejscem, by to zrobić.

Potrafisz już stworzyć własny widok w szablonie blade.php, umiesz ustawiać ścieżki URL i wiązać je z widokami/kontrolerami oraz potrafisz stworzyć widok od zera. Nie jest źle!

Kolejna część będzie poświęcona tematom związanym z modelem.

Przejdź do lekcji czwartej tutaj >>> [4 z 5] Laravel PHP: Model i migracja danych krok po kroku

Przejdź do artykułu poświęconego frameworkowi i spisu wszystkich materiałów tutaj >>> Laravel.

Dajcie znać w komentarzach, czy do tej pory temat Laravela idzie gładko, czy jednak pojawiają się jakieś problemy.

7 Responses on this post

  1. Świetnie, że wchodzisz w temat FW. Czekam na więcej, a po Laravelu myślę, że powinno pojawić się Symfony (lub być może w odwrotnej kolejności)

  2. nie zadzialalo mi
    Route::get(’/hello2′, 'ArticleController@index’);
    dopiero po uzupełnieniu
    Route::get(’/hello2′, 'App\Http\Controllers\ArticleController@index’);

    Czy gdzieś pominąłem jakieś ustawienia?

    1. Cześć Błażej,

      to w dużej mierze zależy od wersji Laravela, z której korzystasz. Raczej nie trzeba nic ustawiać dodatkowo.

      W najnowszej wersji już stosujemy bezpośrednie odniesienie do klasy kontrolera, jak tutaj:
      Route::get(’/faktury’, [InvoicesController::class, 'index’])->name(’invoices.index’);

  3. U mnie również na najnowszej wersji nie zadziałało, trzeba było podać pełną ścieżkę.

Comments are closed.