Interested how Laravel works under the hood? → Check my Laravel Core Adventures Course

All Laravel PHP Attributes at Your Disposal

#laravel

PHP attributes are a great way to add metadata to your classes, methods, and properties. Laravel provides a bunch of them out of the box, you can use in your applications.

Looking for something specific? Jump to the attribute you are interested in:

Observed By

The ObservedBy attribute allows you to define an observer for a model. This is a great way to keep your model clean and move the observer logic to a separate class.

use App\Observers\UserObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
 
#[ObservedBy([UserObserver::class])]
class User extends Authenticatable
{
    //
}

Scoped By

The ScopedBy attribute allows you to define a global scope for a model. This is a handy way to apply common query constraints to a model.

namespace App\Models;
 
use App\Models\Scopes\ActiveScope;
use Illuminate\Database\Eloquent\Attributes\ScopedBy;
 
#[ScopedBy([ActiveScope::class])]
class User extends Model
{
    //
}

Contextual Attributes

Laravel provides a convenient way to handle dependency injection for specific contexts, such as injecting driver implementations or configuration values. Instead of manually setting up contextual bindings in service providers, Laravel offers a range of contextual binding attributes. These attributes streamline the process of injecting context-specific values.

Take a look at the following examples:

namespace App\Http\Controllers;

use Illuminate\Container\Attributes\Auth;
use Illuminate\Container\Attributes\Cache;
use Illuminate\Container\Attributes\Config;
use Illuminate\Container\Attributes\DB;
use Illuminate\Container\Attributes\Log;
use Illuminate\Container\Attributes\Tag;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Contracts\Database\Connection;
use Psr\Log\LoggerInterface;

class PhotoController extends Controller
{
    public function __construct(
        #[Auth('web')] protected Guard $auth,
        #[Cache('redis')] protected Repository $cache,
        #[Config('app.timezone')] protected string $timezone,
        #[DB('mysql')] protected Connection $connection,
        #[Log('daily')] protected LoggerInterface $log,
        #[Tag('reports')] protected iterable $reports,
    )
    {
    // ...
    }
}

Laravel even lets you inject the current User to a route:

use App\Models\User;
use Illuminate\Container\Attributes\CurrentUser;
 
Route::get('/user', function (#[CurrentUser] User $user) {
    return $user;
})->middleware('auth');

Delete When Missing Models

When injecting models into your jobs, you can use the DeleteWhenMissingModels attribute to automatically delete the job if the injected model is missing from the database.

namespace Acme;

use Illuminate\Queue\Attributes\DeleteWhenMissingModels;

#[DeleteWhenMissingModels]
class ProcessPodcastJob
{
    public function __construct(
        public Podcast $podcast,
    ) {}
}

Without Relations

The WithoutRelations attribute allows you to load a model without its relationships. This can be useful when you want to avoid loading unnecessary data.

class ProcessPodcastJob
{
    public function __construct(
        #[WithoutRelations]
        public Podcast $podcast,
    ) {}
}

Custom Eloquent Collections

When you query a model, Eloquent returns a collection of models through Laravel's base Collection class. Sometimes you prefer to use a custom collection class where you can define additional methods or override existing ones. You can achieve this by using the CollectedBy attribute.

#[CollectedBy(PodcastCollection::class)]
class Podcast extends Model
{
    //
}
Note: Read more about it in the Official Docs.

Did I Miss Any?

If you know any other Laravel PHP attributes, please let me know on Twitter or send a PR on GitHub. I would love to add them to this list.

Do you enjoy my posts?

Sign up for my newsletter to receive updates on my latest content.

You will receive monthly updates on my latest articles and products. I do care about the protection of your data. Read my Privacy Policy.