Фишки Laravel #5: полезные советы, новые методы и изменения

Вывод версии Laravel и PHP в Blade

В Blade можно легко получить текущую версию Laravel и PHP с помощью следующих сниппетов:


{{ Illuminate\Foundation\Application::VERSION }}
{{ PHP_VERSION }}
        

Illuminate\Foundation\Application::VERSION — возвращает текущую версию Laravel, установленную в проекте.

PHP_VERSION — возвращает версию PHP, используемую на сервере.

Также можно вывести версию базы данных в контроллере или сервисе:


DB::select(DB::raw('SELECT version()'));
        

Проверка чекбокса в формах без сохранения в БД

В формах регистрации часто требуется чекбокс «Согласен с условиями», который нужно проверять, но не сохранять в базу данных. В Laravel можно использовать exclude для исключения такого поля из валидации перед сохранением:


use Illuminate\Foundation\Http\FormRequest;

class UpdateRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => 'required|string|min:1|max:50',
            'email'=> 'required|string|min:6|max:255|email',
            'accept_terms' => 'required|accepted|exclude',
        ];
    }
}
        

Здесь exclude удаляет поле accept_terms из финального массива валидации, предотвращая его сохранение в БД.

Удаление большого количества записей из базы частями

При массовом удалении записей из таблицы следует делать это порционно с задержками, чтобы не перегружать базу данных:


use App\Models\Log;

$query = Log::where('created_at', '<=', now()->subDays(30));

while ($query->exists()) {
    $query->limit(5000)->delete();
    sleep(3);
}
        

Этот метод поможет избежать блокировки таблицы и снизить нагрузку на сервер.

Новый метод коллекций select в Laravel 10.44

Метод select позволяет извлекать только определённые ключи из элементов коллекции:


$users = collect([
    ['name' => 'Василий Иванов', 'role' => 'Developer', 'status' => 'active'],
    ['name' => 'Ольга Петрова', 'role' => 'Manager', 'status' => 'active'],
]);

$users->select(['name', 'role']);

/*
    [
        ['name' => 'Василий Иванов', 'role' => 'Developer'],
        ['name' => 'Ольга Петрова', 'role' => 'Manager'],
    ],
*/
        

Ранее для подобной выборки приходилось использовать map или only.

Новые атрибуты ObservedBy и ScopedBy в Laravel 10.44

В версии Laravel 10.44 появились новые атрибуты ObservedBy и ScopedBy, которые позволяют назначать наблюдателей (Observers) и области (Scopes) прямо в модели с помощью PHP-атрибутов.

Ранее для регистрации наблюдателей и глобальных областей приходилось прописывать их в методе boot(), а теперь это можно сделать проще.


use App\Observers\FlightObserver;
use App\Scopes\ActiveScope;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;


class Flight extends Model
{
    //
}
        

Эти атрибуты упрощают код и делают его более читаемым.

#[ObservedBy(...)]— атрибут назначает наблюдателя (Observer) для модели. Это класс, который слушает события модели (creating, updating, deleting и т. д.) и выполняет дополнительную логику.

#[ScopedBy(...)]- атрибут подключает глобальную область (Scope) к модели. Scopes применяют дополнительные условия ко всем запросам.

Получение сырого SQL с подставленными значениями

С Laravel 10 стало проще отлаживать запросы с параметрами с помощью метода toRawSql():


User::where('email', 'foo@example.com')->toRawSql();
// "SELECT * FROM users WHERE email = 'foo@example.com'"
        

Раньше приходилось использовать toSql() и вручную подставлять параметры.

Гибкое кэширование в Laravel 11

В Laravel 11 появился новый метод Cache::flexible(), который позволяет обновлять кэшированные данные в фоновом режиме:

use Illuminate\Support\Facades\Cache;
use Carbon\Carbon;

$value = Cache::flexible(
    key: 'my_data',
    ttl: [
        Carbon::minutes(5),  // Период "свежести"
        Carbon::minutes(15)  // Общий жизненный цикл (свежесть + отсрочка)
    ],
    callback: function () {
        // Дорогостоящая операция.
    }
);
        

Этот метод кеширует данные по ключу 'my_data' и определяет две стадии жизни кеша:

Как это работает

«Свежесть» (Soft TTL) — 5 минут: В течение этого времени данные считаются актуальными. Если кто-то запрашивает данные, кеш просто возвращает их без пересчёта.

«Отсрочка» (Hard TTL) — 15 минут (включая Soft TTL): После 5 минут кеш уже считается устаревшим, но остаётся доступным ещё 10 минут. Если в этот период кто-то запросит данные, система может запустить дорогостоящую операцию обновления кеша в фоне, но вернёт старые данные.

Как это помогает?

Избегает перегрузки сервера, так как не позволяет сразу сбрасывать кеш. Предотвращает ситуацию, когда много пользователей одновременно запрашивают одно и то же обновление. Данные обновляются плавно, а не мгновенно по истечении TTL.

Это помогает балансировать между производительностью и актуальностью данных.

Изменения в merge() при обновлении Request в Laravel 12

В Laravel 11 и более ранних версиях при вызове merge() с вложенными ключами использовался «плоский» формат массива:


dump($request->all());
// [ 'user' => ['first_name' => 'Артём'] ]

$request->merge(['user.last_name' => 'Смирнов']);

dump($request->all());
// [ 'user' => ['first_name' => 'Newton'], 'user.last_name' => 'Смирнов' ]
        

Однако в Laravel 12 изменился принцип работы merge(). Теперь он корректно объединяет вложенные ключи:

$request->merge(['user.last_name' => 'Смирнов']);
dump($request->all());
// [ 'user' => ['first_name' => 'Артём', 'last_name' => 'Смирнов'] ]
        

Это делает работу с вложенными структурами более интуитивной и удобной.