Перейти к основному содержимому

Laravel — очереди и политики

Разработчику Архитектору

Laravel — очереди и политики

Две темы, без которых production-приложение на Laravel редко обходится: очереди (долгие задачи вне HTTP-запроса) и политики (кто может что делать с моделью).

Старт проекта: Первая программа на Laravel. Тесты очередей: PHPUnit.


Зачем очереди

Отправка письма, генерация PDF, вызов внешнего API не должны блокировать ответ пользователю. Job кладётся в очередь; worker обрабатывает её в фоне.


Job

php artisan make:job SendWelcomeEmail

app/Jobs/SendWelcomeEmail.php:

<?php

namespace App\Jobs;

use App\Models\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;

class SendWelcomeEmail implements ShouldQueue
{
use Queueable;

public function __construct(public User $user) {}

public function handle(): void
{
Mail::raw(
"Добро пожаловать, {$this->user->name}",
fn ($m) => $m->to($this->user->email)->subject('Регистрация')
);
}
}

Постановка в очередь:

SendWelcomeEmail::dispatch($user);
// или с задержкой:
SendWelcomeEmail::dispatch($user)->delay(now()->addMinutes(5));

Драйвер и worker

.env для разработки:

QUEUE_CONNECTION=database
php artisan queue:table
php artisan migrate
php artisan queue:work

Для production часто Redis + Laravel Horizon (дашборд и балансировка workers).

Тест

use App\Jobs\SendWelcomeEmail;
use Illuminate\Support\Facades\Queue;

Queue::fake();
// ... действие, которое диспатчит job
Queue::assertPushed(SendWelcomeEmail::class);

Политики (Policies)

Правила доступа к модели, например «редактировать пост может только автор».

php artisan make:policy PostPolicy --model=Post

app/Policies/PostPolicy.php:

<?php

namespace App\Policies;

use App\Models\Post;
use App\Models\User;

class PostPolicy
{
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}

public function delete(User $user, Post $post): bool
{
return $user->id === $post->user_id || $user->is_admin;
}
}

Контроллер:

public function update(Request $request, Post $post)
{
$this->authorize('update', $post);
$post->update($request->validated());
return redirect()->route('posts.show', $post);
}

Blade:

@can('update', $post)
<a href="{{ route('posts.edit', $post) }}">Редактировать</a>
@endcan

Gates (разовые проверки)

app/Providers/AppServiceProvider.php:

use Illuminate\Support\Facades\Gate;

public function boot(): void
{
Gate::define('admin-panel', fn ($user) => $user->is_admin);
}
if (Gate::allows('admin-panel')) { /* ... */ }

Policies предпочтительнее для CRUD вокруг модели; Gates — для глобальных флагов.


Middleware vs Policy

MiddlewarePolicy
УровеньМаршрут («залогинен?»)Действие над объектом («это его пост?»)
Примерauth, verifiedupdate, delete

Связанные материалы


См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).