---
title: "Laravel Cooldown: пакет для контролю часових інтервалів між діями"
url: https://laravelukraine.com/blog/laravel-cooldown-paket-dlia-kontroliu-casovix-intervaliv-miz-diiami
author: "Олексій Бабінцев"
date: 2026-07-17
source: https://laravel-news.com/enforce-per-action-waiting-periods-in-laravel-with-cooldown?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed%3A+laravelnews
---

# Laravel Cooldown: пакет для контролю часових інтервалів між діями

Laravel Cooldown - це пакет від [Mahedi Zaman Zaber](https://github.com/zaber-dev), який дозволяє встановлювати часове блокування на іменовані дії. Якщо `RateLimiter` Laravel підраховує кількість запитів до ендпоінту в межах часового вікна, то Cooldown відстежує, чи конкретна дія для конкретного власника все ще перебуває в періоді очікування, і може зберігати цей стан у базі даних, а не лише в кеші.

## Основні можливості

Пакет пропонує широкий набір функцій для роботи з часовими блокуваннями:

- **Дії з прив'язкою до власника** через `Cooldown::for('resend_verification', $user)`, де власником може бути будь-яка модель, IP-адреса у вигляді рядка або відсутність власника для глобального блокування
- **Трейт `HasCooldowns`**, який додає метод `$user->cooldown('change_avatar')` до будь-якої Eloquent-моделі
- **Middleware для маршрутів** у форматі `cooldown:action,duration` з опціональним аргументом драйвера
- **Атомарне виконання** через `block()`, який встановлює блокування навколо callback-функції та активує cooldown лише у разі успіху
- **Метод `enforce()`** для викидання `CooldownActiveException`, яке рендериться як HTTP 429
- **Незмінний об'єкт `CooldownInfo`** з методами `remainingSeconds()` та `remainingForHumans()`
- **Бекенди cache або database**, які можна перемикати для кожного виклику через `using()`
- **Очищення** застарілих записів бази даних через команду Laravel `model:prune`

## Fluent API

Cooldown складається з іменованої дії, опціонального власника та тривалості. Після визначення можна встановлювати, перевіряти або скидати блокування:

```php
use ZaberDev\Cooldown\Facades\Cooldown;
Cooldown::for('rebuild_search_index')->for(600);
Cooldown::for('resend_verification', $user)->for(900);
Cooldown::for('daily_checkin', $user)->until(now()->endOfDay());
```

Коли cooldown активний, метод `info()` повертає об'єкт з деталями тривалості:

```php
if (Cooldown::for('resend_verification', $user)->active()) {
    $info = Cooldown::for('resend_verification', $user)->info();
    echo "Please wait " . $info->remainingForHumans() . " before requesting another email.";
    echo "Seconds remaining: " . $info->remainingSeconds();
}
```

Якщо потрібно зупинити запит замість розгалуження логіки, `enforce()` викидає виключення, коли дія все ще заблокована:

```php
Cooldown::for('request_password_reset', $user)->enforce();
```

## Атомарне блокування

Cooldown створений саме для ситуацій на кшталт відправки OTP або списання коштів з картки, коли два одночасні запити можуть пройти перевірку до того, як будь-який з них встановить блокування. Метод `block()` вирішує цю проблему, отримуючи lock, виконуючи callback і застосовуючи cooldown лише у разі успішного виконання:

```php
Cooldown::for('send_login_code', $user)->block(function () use ($smsClient, $user) {
    $smsClient->sendCode($user->phone);
}, duration: 90);
```

Якщо потрібно управляти блокуванням власноруч, доступні методи `acquireLock()` та `releaseLock()`.

## Cooldown на Eloquent-моделях

Додайте трейт `HasCooldowns`, і той самийBuilder буде доступний на екземплярі моделі з автоматичною прив'язкою до запису:

```php
use ZaberDev\Cooldown\HasCooldowns;

class User extends Authenticatable
{
    use HasCooldowns;
}
```

Використання:

```php
$user->cooldown('change_avatar')->for(300);

if ($user->cooldown('change_avatar')->active()) {
    return response()->json(['message' => 'You can change your avatar again shortly.'], 429);
}

$user->cooldown('change_avatar')->reset();
```

При використанні database-бекенду записи є поліморфними, тому cooldown моделі можна запитувати як будь-яке інше відношення:

```php
$activeCooldowns = $user->cooldowns()->where('expires_at', '>', now())->get();
$user->cooldowns()->delete();
```

## Middleware для маршрутів

Middleware `cooldown` приймає назву дії, тривалість у секундах та опціональний драйвер:

```php
Route::post('/feedback', [FeedbackController::class, 'store'])
    ->middleware('cooldown:submit_feedback,120');

Route::post('/invoices/export', [InvoiceController::class, 'export'])
    ->middleware('cooldown:invoice_export,600,database');
```

## Бекенди для зберігання

За замовчуванням використовується драйвер `cache`, що базується на налаштованому сховищі, тому працюють і Redis, і Memcached. Драйвер `database` натомість записує дані в таблицю `cooldowns`, що корисно, коли блокування пов'язане з критичними операціями на кшталт біллінгу і не може бути видалене під час очищення кешу. Драйвер можна вибирати для кожного виклику:

```php
Cooldown::for('poll_job_status', $ip)->using('cache')->for(20);
Cooldown::for('renew_subscription', $user)->using('database')->for(86400);
```

Якщо потрібне інше сховище, `Cooldown::extend()` дозволяє зареєструвати власний драйвер із service provider. Застарілі записи бази даних можна очищати за розкладом командою Laravel `model:prune`.

## Встановлення

Пакет вимагає PHP 8.2 і підтримує Laravel 11, 12 та 13:

```bash
composer require zaber-dev/laravel-cooldown
php artisan vendor:publish --provider="ZaberDev\Cooldown\CooldownServiceProvider"
php artisan migrate
```

Файл `config/cooldown.php` встановлює драйвер за замовчуванням (`COOLDOWN_DRIVER`), сховище кешу та префікс ключів, назву таблиці бази даних та чи відправляються події.

Інструкції з встановлення та повну документацію можна знайти на [GitHub](https://github.com/zaber-dev/laravel-cooldown).
