Witaj w moim świecie! Dziś na warsztat bierzemy coś, co na pierwszy rzut oka wygląda jak zbawienie, a w rzeczywistości jest koniem trojańskim w Twoim kodzie. Mowa o dyrektywie @inject w Blade.
Pewnie widziałeś artykuły, które ją zachwalają. “Czyste kontrolery!”, “Mniej kodu!”, “Elegancja!”. Brzmi super, prawda? Sam kiedyś tak myślałem. Ale po latach walki w okopach Laravela, powiem Ci jedno: używanie @inject to proszenie się o kłopoty.
Co to w ogóle jest @inject?
Dla niewtajemniczonych, @inject to sprytny sposób, by wstrzyknąć serwis z kontenera Laravela prosto do widoku. Zamiast robić to w kontrolerze, robisz to w pliku .blade.php:
{{-- Gdzieś w Twoim widoku --}}
@inject('stats', 'App\Services\StatisticsService')
<p>Liczba postów: {{ $stats->getPostCount() }}</p>
Twój kontroler staje się chudy jak przecinek. Magia! Ale to iluzja, która drogo kosztuje.
Architektoniczny koszmar w przebraniu
Wyobraź sobie, że Twoja aplikacja to restauracja:
- Kontroler to szef kuchni. On wie, co, jak i z czego przygotować.
- Widok (Blade) to kelner. Jego zadaniem jest podać gościowi to, co przygotował szef kuchni. Ma wyglądać ładnie i apetycznie.
Używając @inject, każesz kelnerowi biegać po kuchni i samemu szukać składników. Nagle Twój kelner, zamiast serwować dania, zaczyna grzebać w lodówkach i przyprawach. Chaos gwarantowany.
Mieszając logikę z prezentacją, tworzysz kod, który jest:
- Trudny do testowania: Jak przetestować logikę, która jest zaszyta w widoku? To jak próbować ocenić smak zupy, patrząc na zdjęcie w menu.
- Nieprzewidywalny: Gdzie te dane są w ogóle używane? Musisz przeszukiwać pliki
.blade.php, żeby znaleźć logikę biznesową. Powodzenia za pół roku! - Mało elastyczny: Chcesz użyć tej samej logiki w API? Albo w konsoli? Ups… jest przyklejona do widoku. Trzeba pisać od nowa.
Jak to zrobić dobrze? Dwa proste sposoby
Zamiast iść na skróty, użyj narzędzi, które Laravel daje Ci od lat. Są sprawdzone w boju i nie zrobią Ci krzywdy.
Sposób 1: Stary, dobry kontroler (90% przypadków)
To najprostsze i najlepsze rozwiązanie. Niech kontroler robi swoją robotę.
// PostController.php
public function show(Post $post, StatisticsService $stats)
{
$postCount = $stats->getPostCount();
return view('posts.show', [
'post' => $post,
'postCount' => $postCount,
]);
}
// posts/show.blade.php
<p>Liczba postów: {{ $postCount }}</p>
Proste, czytelne, testowalne. Każdy wie, gdzie co jest.
Sposób 2: View Composers (gdy dane są wszędzie)
Jeśli jakieś dane (np. liczba powiadomień, menu) muszą być dostępne w wielu widokach, użyj View Composers. To dedykowani “pomocnicy”, którzy przygotowują dane dla widoków.
Definiujesz klasę, która zbiera dane:
// app/View/Composers/NotificationComposer.php
class NotificationComposer
{
public function compose(View $view)
{
$view->with('unreadNotifications', auth()->user()->unreadNotifications()->count());
}
}
I mówisz Laravelowi, kiedy ma jej użyć (np. w AppServiceProvider):
// AppServiceProvider.php
public function boot()
{
View::composer('partials.nav', NotificationComposer::class);
}
Teraz każdy widok partials.nav dostanie zmienną $unreadNotifications. Centralne zarządzanie, zero bałaganu.
Podsumowując: Nie idź na skróty
@inject to jedna z tych funkcji, które brzmią dobrze w teorii, ale w praktyce prowadzą do kodu, którego nikt nie chce utrzymywać.
Pamiętaj o złotej zasadzie: kontrolery kontrolują, widoki wyświetlają.
Trzymaj się jej, a Twoje aplikacje będą solidne, łatwe w rozwoju i przyjemne w pracy. A Ty będziesz spać spokojnie, nie martwiąc się o ukrytą logikę w swoich widokach.
Masz inne zdanie? Zostaw komentarz! Chętnie podyskutuję. A jeśli ten post Ci pomógł, zajrzyj tu za jakiś czas po więcej praktycznych porad od starego wyjadacza.