V moderním vývoji PHP, atributy poskytují strukturovaný způsob přidávání metadat ke třídám, metodám a vlastnostem. Laravel i Livewire tuto funkci přijaly a zavedly několik atributů, které zjednodušují běžné úlohy. Prozkoumejme atributy PHP poskytované kontejnerem Laravel a Livewire spolu s příklady pro každý z nich.
Atributy kontejneru Laravel
Kontejner služeb Laravel obsahuje atributy, které zjednodušují řešení závislostí a vstřikování služeb:
1. #[Auth]
Injektuje správce ověřování do třídy.
Příklad:
use Illuminate\Container\Attributes\Auth;use Illuminate\Contracts\Auth\Guard; class PhotoController extends Controller{ public function __construct( #[Auth('web')] protected Guard $auth, ) { // }}
2. #[Cache]
Injektuje správce mezipaměti do třídy.
Příklad:
use Illuminate\Container\Attributes\Cache;use Illuminate\Contracts\Cache\Repository; class PhotoController extends Controller{ public function __construct( #[Cache('redis')] protected Repository $cache, ) { // }}
3. #[Config]
Vstřikuje konfigurační hodnoty přímo do závislostí tříd.
Příklad:
use Illuminate\Container\Attributes\Config; class PhotoController extends Controller{ public function __construct( #[Config('app.timezone')] protected string $timezone, ) { // }}
4. #[CurrentUser]
Vloží aktuálně ověřeného uživatele.
Příklad:
use Illuminate\Container\Attributes\CurrentUser;use App\Models\User; class PhotoController extends Controller{ public function __construct( #[CurrentUser] User $currentUser ) { // $currentUser is the authenticated user instance }}
5. #[DB]
Vloží konkrétní databázové připojení.
Příklad:
use Illuminate\Container\Attributes\DB;use Illuminate\Database\Connection; class PhotoController extends Controller{ public function __construct( #[DB('mysql')] protected Connection $connection, ) { // $db is the 'mysql' database connection }}
6. #[Log]
Injektuje instanci loggeru do třídy.
Příklad:
use Illuminate\Container\Attributes\Log;use Psr\Log\LoggerInterface; class PhotoController extends Controller{ public function __construct( #[Log('daily')] protected LoggerInterface $log, ) { // $logger is the logger instance }}
7. #[RouteParameter]
Vstřikuje parametr trasy do třídy.
Příklad:
use App\Models\Photo;use Illuminate\Container\Attributes\RouteParameter; class PhotoController extends Controller{ public function __construct( #[RouteParameter('photo')] protected Photo $photo, ) { // }}
8. #[Storage]
Injektuje správce úložiště do třídy.
Příklad:
use Illuminate\Container\Attributes\Storage;use Illuminate\Contracts\Filesystem\Filesystem; class PhotoController extends Controller{ public function __construct( #[Storage('local')] protected Filesystem $filesystem ) { // }}
9. #[Tag]
Označí službu pro pozdější načtení.
Příklad:
use Illuminate\Container\Attributes\Tag; class PhotoController extends Controller{ public function __construct( #[Tag('reports')] protected iterable $reports, ) { // ... }}
10. #[Authenticated]
Vloží aktuálně ověřeného uživatele (volitelně pro daný guard).
Příklad:
use Illuminate\Container\Attributes\Authenticated;use Illuminate\Contracts\Auth\Authenticatable; class PhotoController extends Controller{ public function __construct( #[Authenticated('web')] protected ?Authenticatable $user, ) { // $user is the authenticated user instance (or null) }}
11. #[Bind]
Váže abstraktní závislost na konkrétní třídu.
Příklad:
use Illuminate\Container\Attributes\Bind;use App\Contracts\PaymentGateway;use App\Services\StripeGateway; class CheckoutController extends Controller{ public function __construct( #[Bind(StripeGateway::class)] protected PaymentGateway $gateway, ) { // }}
12. #[Context]
Vyřeší kontextovou hodnotu podle klíče (podporuje výchozí hodnotu).
Příklad:
use Illuminate\Container\Attributes\Context; class PhotoController extends Controller{ public function __construct( #[Context('tenant.id', default: null)] protected ?int $tenantId, ) { // }}
13. #[Database]
Injektuje připojení k databázi (podle názvu/enum).
Příklad:
use Illuminate\Container\Attributes\Database;use Illuminate\Database\Connection; class PhotoController extends Controller{ public function __construct( #[Database('pgsql')] protected Connection $connection, ) { // }}
14. #[Give]
Poskytuje implementaci konkrétní třídy (a parametry) pro kontextové vstřikování závislostí.
Příklad:
use Illuminate\Container\Attributes\Give;use App\Contracts\ReportGenerator;use App\Services\PdfReportGenerator; class ReportsController extends Controller{ public function __construct( #[Give(PdfReportGenerator::class, ['disk' => 'local'])] protected ReportGenerator $generator, ) { // }}
15. #[Scoped]
Označí třídu jako rozmezí v rámci kontejneru.
Příklad:
use Illuminate\Container\Attributes\Scoped; #[Scoped]class RequestCache{ //}
16. #[Singleton]
Označí třídu jako singleton v rámci kontejneru.
Příklad:
use Illuminate\Container\Attributes\Singleton; #[Singleton]class AppWideRegistry{ //}
17. #[Boot]
Označuje vlastnost pro chování při zavádění systému Eloquent.
Příklad:
use Illuminate\Database\Eloquent\Attributes\Boot; #[Boot]trait HasSomethingToBoot{ // ...}
18. #[Initialize]
Označí vlastnost pro inicializační chování Eloquent.
Příklad:
use Illuminate\Database\Eloquent\Attributes\Initialize; #[Initialize]trait HasSomethingToInitialize{ // ...}
19. #[Scope]
Označí metodu jako místní obor.
Příklad:
use Illuminate\Database\Eloquent\Attributes\Scope;use Illuminate\Database\Eloquent\Builder;use Illuminate\Database\Eloquent\Model; class Post extends Model{ #[Scope] public function published(Builder $query): Builder { return $query->where('published', true); }}
20. #[ScopedBy]
Aplikuje na model jeden nebo více globálních oborů.
Příklad:
use Illuminate\Database\Eloquent\Attributes\ScopedBy;use Illuminate\Database\Eloquent\Model;use App\Models\Scopes\TenantScope; #[ScopedBy(TenantScope::class)]class Post extends Model{ // ...}
21. #[ObservedBy]
Registruje jednoho nebo více pozorovatelů pro model.
Příklad:
use Illuminate\Database\Eloquent\Attributes\ObservedBy;use Illuminate\Database\Eloquent\Model;use App\Observers\PostObserver; #[ObservedBy(PostObserver::class)]class Post extends Model{ // ...}
22. #[CollectedBy]
Přiřadí vlastní třídu kolekce k modelu.
Příklad:
use Illuminate\Database\Eloquent\Attributes\CollectedBy;use Illuminate\Database\Eloquent\Model;use App\Collections\PostCollection; #[CollectedBy(PostCollection::class)]class Post extends Model{ // ...}
23. #[UseFactory]
Přiřadí třídu továrny k modelu.
Příklad:
use Illuminate\Database\Eloquent\Attributes\UseFactory;use Illuminate\Database\Eloquent\Model;use Database\Factories\PostFactory; #[UseFactory(PostFactory::class)]class Post extends Model{ // ...}
24. #[UseEloquentBuilder]
Používá vlastní třídu sestavení Eloquent pro model.
Příklad:
use Illuminate\Database\Eloquent\Attributes\UseEloquentBuilder;use Illuminate\Database\Eloquent\Model;use App\Database\PostBuilder; #[UseEloquentBuilder(PostBuilder::class)]class Post extends Model{ // ...}
25. #[UsePolicy]
Přiřadí třídu zásad k modelu.
Příklad:
use Illuminate\Database\Eloquent\Attributes\UsePolicy;use Illuminate\Database\Eloquent\Model;use App\Policies\PostPolicy; #[UsePolicy(PostPolicy::class)]class Post extends Model{ // ...}
26. #[UseResource]
Přiřadí třídu prostředku API k modelu.
Příklad:
use Illuminate\Database\Eloquent\Attributes\UseResource;use Illuminate\Database\Eloquent\Model;use App\Http\Resources\PostResource; #[UseResource(PostResource::class)]class Post extends Model{ // ...}
27. #[UseResourceCollection]
Přiřadí třídu kolekce prostředků API k modelu.
Příklad:
use Illuminate\Database\Eloquent\Attributes\UseResourceCollection;use Illuminate\Database\Eloquent\Model;use App\Http\Resources\PostResourceCollection; #[UseResourceCollection(PostResourceCollection::class)]class Post extends Model{ // ...}
28. #[DeleteWhenMissingModels]
Odstraní úlohu zařazenou do fronty, pokud její související modely nelze při deserializaci nalézt.
Příklad:
use Illuminate\Queue\Attributes\DeleteWhenMissingModels;use Illuminate\Contracts\Queue\ShouldQueue; #[DeleteWhenMissingModels]class ProcessOrder implements ShouldQueue{ // ...}
29. #[WithoutRelations]
Serializuje modely Eloquent v úloze bez relací.
Příklad:
use Illuminate\Queue\Attributes\WithoutRelations;use Illuminate\Contracts\Queue\ShouldQueue; #[WithoutRelations]class SyncCustomer implements ShouldQueue{ // ...}
Atributy zařízení Livewire
Aplikace Livewire zavádí několik atributů, které rozšiřují funkčnost komponent:
1. Computed
Na stránkách #[Computed] atribut je způsob, jak v systému Livewire vytvářet "odvozené" vlastnosti. Podobně jako accessory v modelu Eloquent umožňují vypočtené vlastnosti přistupovat k hodnotám a ukládat je do mezipaměti pro budoucí přístup během požadavku.
Příklad:
use Livewire\Attributes\Computed; class UserProfile extends Component{ public $firstName; public $lastName; #[Computed] public function getFullName() { return "{$this->firstName} {$this->lastName}"; }}
V tomto příkladu, getFullName je vypočtená vlastnost, která kombinuje firstName a lastName.
2. Isolate
Pomocí atributu třídy #[Isolate] aplikace Livewire můžete komponentu označit jako "izolovanou". To znamená, že kdykoli tato komponenta provede obchvat serveru, pokusí se izolovat od ostatních požadavků na komponenty.
Příklad:
use Livewire\Attributes\Isolate; #[Isolate]class TodoList extends Component{ }
To je užitečné, pokud je aktualizace nákladná a raději byste provedli aktualizaci této komponenty paralelně s ostatními.
3. Js
Na stránkách #[Js] atribut se používá k přímému svázání vlastnosti JavaScriptu s komponentou.
Příklad:
use Livewire\Attributes\Js; class NotificationComponent extends Component{ #[Js] public $isVisible = true;}
Tuto vlastnost lze nyní použít přímo v JavaScriptu aplikace k zobrazení nebo skrytí oznámení.
4. Layout
Na stránkách #[Layout] atribut určuje soubor rozvržení, který má komponenta používat.
Příklad:
use Livewire\Attributes\Layout; #[Layout('layouts.dashboard')]class Dashboard extends Component{ }
To by dalo Livewire pokyn k vykreslení komponenty v rámci dashboard uspořádání.
5. Lazy
Komponenty s líným načítáním se plně načtou až po vstupu do zobrazovacího prostoru prohlížeče, například když uživatel na některou z nich přejde.
Příklad:
use Livewire\Attributes\Lazy; #[Lazy]class UserProfile extends Component{ //}
V tomto případě $profileData bude načtena až ve chvíli, kdy je skutečně potřeba.
6. Locked
Na stránkách #[Locked] atribut zabraňuje tomu, aby byla vlastnost upravena frontendem.
Příklad:
use Livewire\Attributes\Locked; class UserSettings extends Component{ #[Locked] public $userId;}
V tomto příkladu je $userId vlastnost nelze aktualizovat z frontendu.
7. Modelable
Na stránkách #[Modelable] atribut se používá pro vazbu pouze jedné vlastnosti podřízené komponenty z její nadřazené komponenty.
Příklad:
use Livewire\Attributes\Modelable; class PostForm extends Component{ #[Modelable] public $title;}
8. On
Na stránkách #[On] atribut váže akci nebo metodu na konkrétní událost.
Příklad:
use Livewire\Attributes\On; class UserRegistered extends Component{ #[On('userRegistered')] public function handleNewUser($user) { // Handle the registration event }}
V tomto příkladu je metoda handleNewUser se zavolá, když se userRegistered je spuštěna událost.
9. Reactive
Na stránkách #[Reactive] atribut označuje vlastnost jako reaktivní, což znamená, že všechny vlastnosti podřízené komponenty se automaticky aktualizují na frontend, když se něco změní v rodičovské komponentě.
Příklad:
use Livewire\Attributes\Reactive; class Counter extends Component{ #[Reactive] public $count = 0; public function increment() { $this->count++; }}
10. Renderless
Na stránkách #[Renderless] atribut se používá k označení, že komponenta nezobrazuje žádné zobrazení, ale lze jej použít pro logické účely.
Příklad:
use Livewire\Attributes\Renderless; class FormLogic extends Component{ #[Renderless] public function validateForm() { // Perform form validation logic }}
Tato třída nebude vykreslovat žádné zobrazení, ale může zpracovávat logiku ověřování formuláře.
11. Rule
Na stránkách #[Rule] slouží k definování vlastních pravidel ověřování vlastností komponenty.
Příklad:
use Livewire\Attributes\Rule; class RegisterUser extends Component{ #[Rule('required|string|max:255')] public $username;}
Tím se vynutí ověřovací pravidlo pro $username nemovitosti.
12. Session
Na stránkách #[Session] atribut váže vlastnost komponenty na relaci.
Příklad:
use Livewire\Attributes\Session; class UserProfile extends Component{ #[Session] public $theme;}
Tím se uloží $theme v relaci, takže přetrvává napříč požadavky.
13. Title
Na stránkách #[Title] atribut umožňuje zadat název zobrazení komponenty.
Příklad:
use Livewire\Attributes\Title; #[Title('My Custom Page Title')]class PageTitle extends Component{ public function render() { return view('page'); }}
Tím nastavíte název stránky na "Můj vlastní název stránky".
14. Url
Na stránkách #[Url] atribut váže vlastnost na adresu URL.
Příklad:
use Livewire\Attributes\Url; class Navigation extends Component{ #[Url] public $currentUrl = '';}
Díky tomu je $currentUrl automaticky odráží adresu URL aktuální stránky.
15. Async
Na stránkách #[Async] atribut umožňuje paralelní běh metody akce bez blokování ostatních požadavků.
Příklad:
use Livewire\Attributes\Async; class PostShow extends Component{ #[Async] public function logActivity() { // fire-and-forget side effect }}
16. Defer
Na stránkách #[Defer] atribut odloží načtení komponenty až na dobu po dokončení počátečního načtení stránky.
Příklad:
use Livewire\Attributes\Defer; #[Defer]class RevenueWidget extends Component{ //}
17. Json
Na stránkách #[Json] atribut označuje akci jako koncový bod JSON, takže může vracet data přímo do JavaScriptu.
Příklad:
use Livewire\Attributes\Json; class Search extends Component{ #[Json] public function search($query) { return []; // return JSON directly to JS }}
18. Validate
Na stránkách #[Validate] atribut spojuje pravidla ověřování s vlastnostmi komponenty.
Příklad:
use Livewire\Attributes\Validate; class PostCreate extends Component{ #[Validate('required|min:3')] public $title = ''; public function save() { $this->validate(); // }}
Závěr
S 45+ atributů PHP v Laravelu a Livewire mají vývojáři k dispozici širokou škálu nástrojů pro zjednodušení pracovních postupů, zlepšení přehlednosti kódu a využití moderních postupů PHP. Tyto atributy snižují množství šablon a přinášejí do vašich aplikací expresivní, deklarativní kódování.