В Laravel всё по умолчанию синхронно. Это значит: написал функцию — ждёшь, пока она там закончится, прежде чем двигаться дальше. Если у тебя хоть раз была задача, которая тупо зависает на пару секунд (например, обработка 100500 изображений или внешние API), ты знаешь, что это полный трэш. Есть два нормальных способа: очереди и асинхронные HTTP-запросы.
Очереди задач (Queues)
Если тебе нужно что-то долгосрочное — отправка письма, обработка файлов, какие-то тяжёлые вычисления — очереди твой лучший друг. Да, звучит скучно, но они реально делают жизнь проще.
Пример:
Создаём задачу через Artisan:
php artisan make:job ProcessData
Внутри класса реализуем метод handle():
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessData implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $data;
public function __construct($data)
{
$this->data = $data;
}
public function handle()
{
// Логику обработки данных сюда. Всё что угодно, пока не тормозит основной поток
}
}
Отправляем задачу в очередь:
ProcessData::dispatch($data);
Пока Laravel таскает эту задачу по очереди, твой основной поток работает дальше, а ты можешь пить кофе и не думать о том, что сервер завис.
Если задача реально тяжёлая — подключай supervisor или horizon. Без этого твои очереди будут выглядеть как кучка заблудших подростков на старом сервере.
Асинхронные HTTP-запросы
Иногда нужно дернуть внешний сервис и не ждать ответа. Стандартный file_get_contents() или Http::get() здесь сразу превращают всё в тормоз. Решение — Guzzle с асинхронным клиентом или что-то на базе swoole/reactphp.
Пример с Guzzle:
composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client(['base_uri' => 'http://example.com']);
$promises = [
'req1' => $client->getAsync('/endpoint1'),
'req2' => $client->getAsync('/endpoint2'),
];
$results = Promise\settle($promises)->wait();
// Обрабатываешь результаты, когда придут. Пока Laravel гоняет, основной поток свободен. Да, придётся заморочиться с обработкой ошибок. Если не проверять результаты, через месяц придёт какая-нибудь дичь: деньги не списались, письма не отправились, а ты будешь искать виновного в очередях, хотя виноват PHP и твоя лень.
Лайфхак от практика
- Не пытайся сделать всё асинхронным. PHP это не Node.js, и ломать голову ради пары миллисекунд — идиотизм.
- Очереди — не про магию, а про порядок и терпение. Настрой
retry,failed_jobs, и всё заработает. - Асинхронные HTTP-запросы — круто, если реально много API и ждать их ответа нельзя. Но ошибки придётся ловить самому.
В общем, если коротко: хочешь, чтобы Laravel не стоял с пистолетом в руке и не заставлял ждать каждую функцию — используй очереди и асинхронные HTTP. Остальное — игры для любителей "чистого кода". Настоящие проекты выживают на том, что работает, а не на красивых абстракциях.
Ты запускаешь задачи — они делают своё дело. Ты идёшь дальше. И никто, кроме тебя, не будет ждать, пока твой сервер обрабатывает гигабайт изображений или дергает внешние API.
0 комментариев