Laravel 13 pozwala teraz zastąpić właściwości $table, $fillable i $casts, które zagracają większość modeli, natywnymi atrybutami PHP. Zmiana ta dotyczy ponad tuzina funkcji frameworka, od konfiguracji modeli po listenerów zdarzeń i mailables, i działa bez łamania istniejącego kodu.

Dlaczego Laravel wprowadził natywne atrybuty

Laravel od dawna polegał na „magicznych ciągach znaków” (magic strings) – tablicach nazw kolumn lub ukrytych pól, które znajdują się na górze klasy modelu. Tablice te nie dają IDE żadnej wskazówki na temat podległego schematu, więc zmiana nazwy kolumny może umknąć uwadze. Przenosząc konfigurację do rzeczywistego, typowanego kodu, Laravel daje programistom sposób na utrzymanie ciała klasy skoncentrowanego na logice biznesowej, jednocześnie pozwalając edytorowi na obsługę autouzupełniania, sprawdzania typów i narzędzi do refaktoryzacji nazw.

Framework odczytuje atrybuty za pomocą PHP Reflection API i buforuje wynik, dzięki czemu narzut w czasie działania (runtime) jest praktycznie zerowy. Istniejące modele oparte na właściwościach nadal działają dokładnie tak samo jak dotychczas, co oznacza, że nową składnię można wdrażać stopniowo.

Co zyskujesz

  • Typowana konfiguracja – Atrybuty przyjmują typowane argumenty, eliminując „magiczne ciągi znaków”. Zmień nazwę kolumny, a IDE wskaże każde miejsce, które wymaga aktualizacji.
  • Czystsze ciała klas – Cała konfiguracja znajduje się powyżej nazwy klasy; ciało klasy zawiera jedynie relacje, zakresy (scopes) i metody.
  • Lepsze doświadczenia z IDE – Autouzupełnianie i analiza statyczna działają na argumentach atrybutów, czego tablice ciągów znaków nie mogą zapewnić.
  • Brak zmian naruszających kompatybilność – Laravel odczytuje zarówno stare właściwości, jak i nowe atrybuty, więc mieszany kod źródłowy działa bez problemów.

Przewodnik migracji krok po kroku

  1. Zidentyfikuj model do migracji
    Otwórz plik modelu. Jeśli pierwsze kilkanaście linii zdominowanych jest przez $table, $fillable, $hidden lub metodę casts(), jest on odpowiednim kandydatem.

  2. Dodaj klasy atrybutów
    Na górze pliku zaimportuj klasy atrybutów odpowiadające właściwościom, które będziesz zastępować (np. Table, Fillable, Casts). Laravel dostarcza te atrybuty w standardzie.

  3. Zastąp deklaracje właściwości atrybutami

    // Before
    protected $table = 'site_deployments';
    protected $fillable = ['site_id', 'server_id', 'status'];
    protected function casts(): array
    {
        return ['is_rollback' => 'boolean'];
    }
    
    // After
    #[Table('site_deployments')]
    #[Fillable(['site_id', 'server_id', 'status'])]
    #[Casts(['is_rollback' => 'boolean'])]
    class Deployment extends Model
    {
        // business logic only
    }
    

    Składnia atrybutów znajduje się bezpośrednio nad deklaracją klasy. Usuń oryginalną właściwość lub metodę po potwierdzeniu, że atrybut działa poprawnie.

  4. Uruchom zestaw testów
    Zweryfikuj, czy masowe przypisywanie (mass-assignment), serializacja i wszelkie niestandardowe rzutowanie (casting) nadal działają tak samo jak wcześniej. Obsługa atrybutów w Laravelu jest buforowana, więc nieudany test zazwyczaj wskazuje na literówkę w argumentach atrybutu.

  5. Commituj i wdrażaj w małych partiach
    Wypchnij (push) zmigrowany model do gałęzi funkcjonalnej (feature branch), scal go po przejściu potoku CI i wdróż na podzbiór serwerów. Ponieważ stara składnia właściwości jest nadal wspierana, jakiekolwiek przypadkowe odwołanie nie spowoduje błędu w czasie działania aplikacji.

  6. Powtarzaj dla każdej przestrzeni nazw (namespace)
    Zamiast przepisywać cały kod źródłowy naraz, przenieś jedną logiczną grupę modeli (np. wszystkie encje związane z rozliczeniami) na atrybuty, a następnie powtórz to dla kolejnej grupy. Ogranicza to zakres ewentualnych regresji.

Narzędzia i zabezpieczenia

  • Rector – Automatyczne narzędzie do refaktoryzacji, które może przekształcić powtarzalną składnię właściwości w atrybuty. Uruchom je na kopii kodu źródłowego, przejrzyj różnice (diff) i zastosuj zmiany, które wyglądają na poprawne.
  • Automatyczne testy – Wbudowane narzędzia testowe Laravela wyłapują rozbieżności w masowym przypisywaniu i wyjściu JSON. Dbaj o to, aby po każdym kroku migracji testy były „zielone”.
  • Flagi funkcji (feature flags) – Jeśli potrzebujesz szybko wycofać zmiany, owiń użycie nowych atrybutów w flagę, która przełącza między starą a nową konfiguracją.

Kiedy można pominąć migrację

Jeśli projekt jest mały, stabilny i rzadko dotykany, korzyść z czystszych modeli może nie przeważyć nad wysiłkiem związanym z konwersją. Składnia atrybutów jest opcjonalna; możesz bez końca korzystać z klasycznego podejścia opartego na właściwościach. Z drugiej strony, w aktywnie rozwijanych aplikacjach, zwłaszcza tych z dużymi modelami lub częstymi zmianami schematu, wcześniejsze przyjęcie atrybutów zmniejsza przyszłe trudności.

Co warto śledzić dalej

Obsługa atrybutów w Laravel 13 wykracza poza modele, obejmując listenerów zdarzeń, powiadomienia, mailables i zdarzenia broadcast. W miarę jak społeczność będzie wdrażać tę składnię w tych obszarach, pojawią się podobne wzorce refaktoryzacji. Śledź oficjalny przewodnik aktualizacji (upgrade guide) pod kątem nowych klas atrybutów, które pojawią się w przyszłych wydaniach typu minor.

Podsumowanie: Laravel 13 oferuje bezkosztową ścieżkę do tworzenia lżejszych i bardziej przyjaznych dla IDE modeli. Konwertuj jedną przestrzeń nazw naraz, polegaj na Rectorze i swoim zestawie testów, a otrzymasz klasy, które czyta się jak specyfikacje biznesowe, a nie pliki będące zrzutem konfiguracji.