[4 z 5] Laravel PHP: Model

Czas na pierwszy model w Laravelu

Modelem w Laravelu nazywamy klasę, która w bezpośredni sposób odpowiada tabeli w bazie danych.

Przy pomocy modelu będziesz mógł w wygodny sposób operować na danych pobranych z bazy. Dostaniesz obiekt w PHP, który posiada odpowiadające pola oraz zestaw metod do pobierania, dodawania i nadpisywania danych.

Tworzymy nowy model

Podobnie jak w przypadku kontrolera w Laravelu, nie będziemy ręcznie dodawać pliku. Skorzystamy z konsolowego narzędzia php artisan, które zdążyłeś poznać 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:model Article

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

Zajrzyj teraz do swojego projektu do folderu głównego app. Powinieneś w nim zauważyć nowy plik o nazwie Article.php tuż przed obecnym już tam User.php.

Laravel model w projekcie

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

Otwórz go teraz i zobacz zawartość:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    //
}

Podobnie jak przy kontrolerze, mamy już ustawiony odpowiedni namespace oraz zdefiniowaną klasę, która rozszerza klasę bazową Model. Tak przygotowana klasa będzie już potrafiła porozumieć się z tabelą w bazie.

Do podstawowego działania nie muszę już niczego dodawać w tej klasie.

Jak zatem Laravel wiąże sobie konkretne tabele z modelami w kodzie? Dzieje się to za pomocą konwencji nazw. Tak nazwany model będzie współpracował z tabelą o nazwie “articles”. Zamieniamy pierwszą literę na małą i dopisujemy s, by uzyskać liczbę mnogą słowa. Tym sposobem dostajemy nazwę tabeli.

Jeśli bardzo chciałbyś, żeby model współpracował z inną tabelą, możesz dodać w nim pole protected $table zawierające nazwę tabeli. Zobacz przykład:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    // ten model odnosi się do tabeli blog_articles
    protected $table = 'blog_articles';
}

Laravel i migracje

Migration tool to narzędzie w Laravelu, które pozwoli Ci stworzyć nową tabelę w bazie bazując na definicji w kodzie PHP. Wewnątrz metody PHP wskazujesz, jakie kolumny ma zawierać tabela, jakiego typu i jakiej nazwy, po czym narzędzie do migracji stworzy je w bazie danych za Ciebie.

Mamy przygotowany model, ale nie ma niczego pod spodem, z czym nasz model mógłby się skomunikować. Potrzebujemy bazy danych wraz z odpowiednią tabelą, by zaprzęgnąć model do pracy.

Zacznijmy od dodania lokalnej bazy danych.

Lokalna instalacja SqLite

W tej serii skorzystamy z bazy danych SqLite. Jest to relacyjna baza danych SQL oparta na jednym pliku z otwartym dostępem do danych. Jej instalacja jest najszybsza i nie wymaga żadnych dodatkowych narzędzi do działania. W środowisku produkcyjnym często potrzebujemy dostępu dla wielu różnych użytkowników z ograniczonymi uprawnieniami, ale nie wykorzystamy tego w lokalnej nauce.

Żeby uruchomić SqLite w Laravelu:

  1. Otwórz plik php.ini w katalogu, gdzie zainstalowałeś php na komputerze (w moim przypadku to C:/php, czyli C:/php/php.ini).
  2. [Dla PHP 7.0 wzwyż] Odszukaj linijkę ;extension=pdo_sqlite i usuń średnik z początku linijki. Dla starszych wersji PHP linijka powinna wyglądać tak: ;extension=’php_pdo_sqlite.dll’. Również musisz usunąć średnik z początku linijki.
  3. Stwórz nowy pusty plik w katalogu database i nazwij go database.sqlite.
  4. W projekcie otwrórz plik config/database.php i zmień  ‘default’ => env(‘DB_CONNECTION’, ‘mysql’) na  ‘default’ => env(‘DB_CONNECTION’, ‘sqlite’).
  5. W katalogu głównym projektu w pliku .env zmień pola DB_CONNECTION oraz DB_DATABASE na, kolejno: sqlite oraz ścieżkę do pliku z bazą. Zobacz jak wygląda to u mnie poniżej:

Konfiguracja DB Sqlite

Nie zmieniaj nic poza tymi dwoma parametrami. Pozostałe parametry dla baz danych przydadzą się przy pozostałych typach połączeń – jak MySQL czy PostgreSQL. Póki co mogą zostać nieruszone. Pamiętaj o podwójnych backslashach przy podawaniu ścieżki do bazy jeśli uruchamiasz skrypt w środowisku Windows. Inaczej możesz dostać błąd, że aplikacja nie może odnaleźć bazy.

Zanim stworzymy swoją pierwszą migrację, zobaczmy, czy baza danych jest poprawnie zainstalowana i widoczna przez nasz skrypt.

Uruchom ponownie konsolę i wpisz:

C:\php-source\blog> php artisan migrate

W rezultacie, jeśli wszystko poszło jak należy, dostaniesz:

C:\php-source\blog> php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table

Tworzymy nową migrację

Gdy połączenie z bazą jest już ustanowione, możemy stworzyć pierwszą migrację. W ten migracji chcemy stworzyć nową tabelę dla modelu Article i zdefiniować potrzebne kolumny.

Zacznijmy od konsoli i polecenia:

C:\php-source\blog> php artisan make:migration create_articles_table

Nazwa migracji jest dowolna, natomiast dobrze jest trzymać się konwencji narzuconej przez twórców. Niech nazwa migracji określa, co kod w niej zamierza wykonać. W naszym przypadku chcemy utworzyć tabelę articles, stąd nazwa create_articles_table. Dla chętnych: porównajcie kod utworzony dla takiej nazwy migracji z kodem utworzonym dla migracji o nazwie articles_migration.

Stworzony plik znajdzie się w katalogu database\migrations:

Stworzona nowa migracja

Zobaczmy teraz na kod wewnątrz utworzonego pliku:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateArticlesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
}

Każdy plik z migracją tworzy klasę rozszerzającą klasę bazową Migration. Każda nowa klasa posiada metodę up oraz down. Metoda up uruchamia się za każdym razem gdy wykonujemy migrację (czyli poprzednia komenda: php artisan migrate) a metoda down zawsze, gdy cofamy zmiany dokonane przez migrację. O tym nie będziemy teraz mówić, natomiast metoda do wycofania zmian na bazie to: php artisan migrate:rollback.

OK, jak widzisz w metodzie up, Laravel domyślnie chce stworzyć nam tabelę o nazwie articles z auto-inkrementowanym polem id oraz timestampami (created_at i updated_at). Artykuł, oprócz tego, powinien zawierać tytuł oraz zawartość. Zobacz, jak dodać te dwie dodatkowe kolumny:

/**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title', 255);
            $table->text('content');
            $table->timestamps();
        });
    }

Pełną listę dostępnych konfiguracji dla tworzonej kolumny znajdziesz w oficjalnej dokumentacji Laravela na: https://laravel.com/docs/5.8/migrations#creating-columns.

Gdy uzupełniłeś kolumny wpisz ponownie w konsoli:

C:\php-source\blog> php artisan migrate

Powinieneś zobaczyć kolejną migrację zakończoną sukcesem. Teraz, jeśli korzystasz z VS Code (jak w moim przypadku) możesz doinstalować sobie rozszerzenie “SQLITE Explorer” i zobaczyć podgląd bazy wraz z tabelami. Zobacz, że pojawiła się tabela articles z uzupełnionymi kolumnami:

Eksplorer sqlite

Teraz model Article może w pełni skorzystać z danych w bazie. Tym zajmiemy się w kolejnej części tutoriala.

Podsumowanie

Model odpowiada za warstwę danych w aplikacji.

Posiada odpowiednie metody do wyciągania danych z bazy i przedstawiania ich postaci obiektów PHP.

W przypadku Laravela za wszystko odpowiada jedna klasa, która rozszerza klasę bazową Model. Postawiono tutaj na szybkość tworzenia kodu, rezygnując z dodatkowej separacji warstwy bazodanowej od warstwy encji i dalej repozytoriów dla reszty kodu. Nie zaprzątaj sobie jednak tym głowy.

Dodatkowo, dzięki Laravelowi możemy tworzyć tabelę w bazie w podejściu tzw. code first. Najpierw definiujemy strukturę danych w kodzie PHP, który później, podczas migracji, jest tłumaczony na język SQL i na jego podstawie tworzą się faktyczne tabele w bazie.

Plus, dowiedziałeś się czym jest SQLite i bardzo sprawnie postawiłeś w pełni działające lokalne środowisko deweloperskie.

Podsumowując, potrafisz stworzyć nowy model oraz dodać towarzyszącą mu migrację danych. Brawo!

Kolejna część będzie poświęcona faktycznemu wykorzystaniu modelu w prezentowaniu użytkownikowi danych z bazy.

Możesz już teraz przejść do piątej, ostatniej lekcji tutaj >>> [5 z 5] Laravel PHP: Model i dane testowe krok po kroku

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

6 Responses on this post

  1. $User->where(…)->width(comments)->first()

    W kwestii gramatyki php czy nawet Laravela, bo to też nie jest oczywiste. Taki oto zapis – co on oznacza? Niby zwykły operator obiektu a jest niejasny. Jak to wielokrotne wywołanie operatora -> działa? Wydaje się, że first() odnosi się do pierwszego obiektu mamy dwa modele user i comments) a nie drugiego. Operator -> wygląda (ma za sobą funkcje) na dwukrotne wywołanie funkcji tego samego obiektu w jednym zapisie.

    W takim razie jak zapisać pierwsze pobranie first() rekordu z tabeli comments?

  2. Hej Tomaszu,

    w PHP operator -> (czyli tzw. dzida) działa tak samo, jak kropka w .NET czy JAVIE. Dzidą odnosisz się do metody lub pola danego obiektu.

    Co do metod “where”, “width” itp. to znowu – jest to świetna analogia np. do LINQ w .NET. Uproszczone konstruowanie zapytań.

    Żeby to lepiej zrozumieć, zawsze analizuj kod od lewej do prawej. Każda dzida tyczy się tego, co ma po swojej lewej. Metoda first() po swojej lewej ma metodę with(comments), która to po lewej ma metodę where, która po lewej ma model Usera. Czyli idąc po kolei, na modelu User (czyli tabeli users) wykonaj warunek where i zwróć wszystkich userów, którzy spełniają warunek. Następnie metodą with(comments) uzupełnić model danych o kompletny model Comments, pasujący dla pobranych Userów (standardowo jeden user ma pewnie wiele komentarzy w osobnej tabeli, połączonej kluczem obcym, które zostaną automatycznie pobrane z userem). Na końcu, metoda first() pobiera pierwszego usera z komentarzami, który znajdował się z liście zwróconej w metodzie with.

    Generalnie, to działa podobnie jak wzorzec Budowniczy (z ang. Builder).

    Metody wykonują operację na obiekcie, po czym zwracają obiekt jako rezultat metody.

    Wtedy jest możliwe wykonanie takich operacji, jak:
    $user = new User();
    $user->setName(‘Marcin’)->setLastName(‘Wesel’)->setAge(30);

    Każda metoda zwraca obiekt User, na którym znowu możemy wykonać kolejną metodę.

    W przypadku konstruowania zapytać jest podobnie, ale część metod zwraca inny typ danych (jak np. first, który zwróci już tylko pojedyczny rekord, a nie listę jak where czy with).

    Mam nadzieję, że trochę rozjaśniłem temat. Jakby co, to pytaj dalej.

    Pozdrawiam,
    Marcin

  3. Właśnie natknąłem się na tego bloga i muszę przyznać, że wiele można się z niego dowiedzieć. W php nie siedzę tak długo, w zasadzie dopiero zaczynam, jednak bardzo mnie to zainteresowało i planowałbym się tym zająć w przyszłości. Nie wiem jednak, czy nie iść na jakieś szkolenie, bo interakcji z nauczycielem nie da się zastąpić a braków mam sporo 🙂

  4. Czy aby Laravel jest najlepszym frameworkiem do nauki PHP? Nie jestem pewien. Ja poznałem Laravela po Symfony. I jest dla mnie trochę odpowiednikiem jQuery w JavaScript. Łatwy i przyjemny, ale poznasz języka. Symfony wymaga samodzielnej konfiguracji, przeszukiwania dokumentacji, instalacji bundli, zrozumienia wzorców projektowych etc.
    Po pól roku pracy z Symfony – Laravel to jest dla mnie spacerek . Dokładnie tak samo jak “nauka” jQuery po poznaniu JavaScript. Spotkałem się natomiast z kilkoma opiniami, że nauka w drugą stronę nie jest tak łatwa.

    1. Hej Marcin, dzięki za komentarz!

      Trudno się z nim nie zgodzić. Jeśli chodzi o proces samej nauki PHP, to jestem gorącym zwolennikiem robienia tego bez jakichkolwiek frameworków. Nawet wzorzec MVC czy inne wzorce projektowe warto zaimplementować samodzielnie, by później móc sprawniej korzystać z gotowców.

      Bardzo mocną stroną Laravela jest właśnie ta gotowa konfiguracja i wszystkie najpotrzebniejsze biblioteki już gotowe do użycia. Jasne, że skonfigurowany zgodnie z potrzebami Symfony, skrojony pod konkretny projekt, będzie działał szybciej. Jednak żyjemy w takich czasach, że soft najpierw się wypuszcza, a później naprawia. Widać to np. po ostatniej premierze CyberPunka z CDP. Jednak kasa musi się zgadzać i oprogramowanie musi zarabiać. Dlatego jestem zwolennikiem jak najszybszego wydawania aplikacji. Jeśli Laravel mi to zapewnia, to w niego idę i też polecam innym.

      1. Witam

        Miałem na myśli osoby początkujące z PHP. Jak odróżniasz interfejs od klasy i klasy abstrakcyjnej, potrafisz używać wzorców projektowych i zdajesz sobie sprawę dlaczego Laravel jest tak prosty – to używaj czego chcesz. Jak masz takie podstawy to szybko poradzisz sobie z TypeScript czy Python. Po zapoznaniu się z gotowymi metodami Laravela, – nie znasz PHP.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *