Руководство по обновлению
- Изменения с высоким уровнем влияния
- Изменения со средним уровнем влияния
- Обновление с 12.x до 13.0
- Обновление с помощью AI
- Обновление зависимостей
- Обновление Laravel Installer
- Cache
- Контейнер
- Контракты
- База данных
- Eloquent
- HTTP Client
- Notifications
- Queue
- Маршрутизация
- Scheduling
- Security
- Support
- Utilities
- Представления
- Разное
Изменения с высоким уровнем влияния
Изменения со средним уровнем влияния
Изменения с низким уровнем влияния
- Префиксы кеша и имена session cookies
- Сериализация коллекций моделей восстанавливает жадно загруженные связи
Container::callи значения nullable-классов по умолчанию- Приоритет регистрации доменных маршрутов
- Payload исключения события
JobAttempted - Привязка callback-функции для
extendв менеджере - Запросы MySQL
DELETEсJOIN,ORDER BYиLIMIT - Имена Bootstrap-представлений для пагинации
- Генерация имени полиморфной сводной таблицы
- Переименование свойства события
QueueBusy - Сброс factories
Strмежду тестами
Обновление с 12.x до 13.0
Оценочное время обновления: 10 минут
Мы стараемся документировать все возможные критические изменения. Поскольку часть этих изменений находится в редко используемых областях фреймворка, только некоторые из них могут затронуть ваше приложение. Чтобы сэкономить время, можно использовать Shift. Shift – поддерживаемый сообществом сервис, который автоматизирует обновления Laravel.
Обновление с помощью AI
Вы можете автоматизировать обновление с помощью Laravel Boost. Boost – официальный MCP-сервер, который предоставляет вашему AI-ассистенту направленные prompt для обновления. После установки в любое приложение Laravel 12 используйте slash-команду /upgrade-laravel-v13 в Claude Code, Cursor, OpenCode, Gemini или VS Code, чтобы начать обновление до Laravel 13. Для этой команды требуется Laravel Boost ^2.0.
Обновление зависимостей
Вероятность влияния: высокая
Зависимости Composer
Обновите следующие зависимости в вашем файле composer.json:
laravel/frameworkдо^13.0laravel/boostдо^2.0laravel/tinkerдо^3.0phpunit/phpunitдо^12.0pestphp/pestдо^4.0
Обновление Laravel Installer
Если вы используете Laravel installer CLI tool для создания новых Laravel-приложений, обновите installer для совместимости с Laravel 13.x.
Если Laravel installer установлен через composer global require, обновите installer командой composer global update:
composer global update laravel/installer
Или, если вы используете копию установщика Laravel, поставляемую с Laravel Herd, обновите Herd до последнего релиза.
Cache
Префиксы кеша и имена session cookies
Вероятность влияния: низкая
Префиксы кеша и ключей Redis по умолчанию в Laravel теперь используют суффиксы через дефис.
В большинстве приложений это изменение не применяется, потому что конфигурационные файлы уровня приложения уже определяют эти значения. В основном оно влияет на приложения, которые полагаются на резервную конфигурацию уровня фреймворка, когда соответствующие значения отсутствуют в конфигурации приложения.
Если ваше приложение зависит от этих сгенерированных значений по умолчанию, ключи кеша и имена session cookie могут измениться после обновления:
// Laravel <= 12.x
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_cache_';
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_database_';
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_session';
// Laravel >= 13.x
Str::slug((string) env('APP_NAME', 'laravel')).'-cache-';
Str::slug((string) env('APP_NAME', 'laravel')).'-database-';
Str::slug((string) env('APP_NAME', 'laravel')).'-session';
Чтобы сохранить прежнее поведение, явно настройте CACHE_PREFIX, REDIS_PREFIX и SESSION_COOKIE в окружении.
Контракты Store и Repository: touch
Вероятность влияния: очень низкая
Контракты кеша теперь включают метод touch для продления TTL элементов. Если вы поддерживаете пользовательские реализации хранилища кеша, добавьте этот метод:
// Illuminate\Contracts\Cache\Store
public function touch($key, $seconds);
Конфигурация кеша serializable_classes
Вероятность влияния: средняя
Конфигурация cache приложения по умолчанию теперь включает опцию serializable_classes, установленную в false. Это усиливает безопасность десериализации кеша и помогает предотвратить цепочки атак через PHP-десериализацию, если APP_KEY вашего приложения утечет. Если приложение намеренно хранит PHP-объекты в кеше, явно перечислите классы, которые можно десериализовать:
'serializable_classes' => [
App\Data\CachedDashboardStats::class,
App\Support\CachedPricingSnapshot::class,
],
Если приложение раньше полагалось на десериализацию произвольных кешированных объектов, нужно перенести такой код на явные списки разрешенных классов или на payload кеша без объектов, например массивы.
Контейнер
Container::call и значения nullable-классов по умолчанию
Вероятность влияния: низкая
Container::call теперь учитывает значения по умолчанию для nullable-параметров классов, когда привязка отсутствует, что соответствует поведению внедрения зависимостей через конструктор, представленному в Laravel 12:
$container->call(function (?Carbon $date = null) {
return $date;
});
// Laravel <= 12.x: Carbon instance
// Laravel >= 13.x: null
Если ваша логика внедрения зависимостей при вызове метода зависела от прежнего поведения, ее может потребоваться обновить.
Контракты
Контракт Dispatcher: dispatchAfterResponse
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Bus\Dispatcher теперь включает метод dispatchAfterResponse($command, $handler = null).
Если вы поддерживаете пользовательскую реализацию диспетчера, добавьте этот метод в ваш класс.
Контракт ResponseFactory: eventStream
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Routing\ResponseFactory теперь включает сигнатуру eventStream.
Если вы поддерживаете пользовательскую реализацию этого контракта, добавьте этот метод.
Контракт MustVerifyEmail: markEmailAsUnverified
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Auth\MustVerifyEmail теперь включает markEmailAsUnverified().
Если у вас есть пользовательская реализация этого контракта, добавьте этот метод для совместимости.
База данных
Database upsert с MySQL или MariaDB
Вероятность влияния: средняя
Laravel теперь проверяет, что caller передал непустое значение uniqueBy, и выбрасывает InvalidArgumentException вместо генерации некорректного SQL.
Хотя database drivers MariaDB и MySQL игнорируют значение uniqueBy и всегда используют primary и unique indexes таблицы для обнаружения существующих записей, validation все равно применяется. Если uniqueBy пустой, будет выброшен InvalidArgumentException.
Запросы MySQL DELETE с JOIN, ORDER BY и LIMIT
Вероятность влияния: низкая
Laravel теперь компилирует полные запросы DELETE ... JOIN, включая ORDER BY и LIMIT, для грамматики MySQL.
В предыдущих версиях выражения ORDER BY / LIMIT могли молча игнорироваться для удалений с JOIN. В Laravel 13 эти выражения включаются в сгенерированный SQL. В результате движки баз данных, которые не поддерживают такой синтаксис, например стандартные варианты MySQL / MariaDB, теперь могут выбросить QueryException вместо выполнения неограниченного удаления.
Eloquent
Загрузка моделей и вложенное создание экземпляров
Вероятность влияния: очень низкая
Создание нового model instance во время booting этой же model теперь запрещено и выбрасывает LogicException.
Это влияет на код, который создает models внутри model boot methods или trait boot* methods:
protected static function boot()
{
parent::boot();
// Больше не разрешено во время booting...
(new static())->getTable();
}
Перенесите эту логику за пределы boot cycle, чтобы избежать nested booting.
Генерация имени polymorphic pivot table
Вероятность влияния: низкая
Когда table names выводятся для polymorphic pivot models с custom pivot model classes, Laravel теперь генерирует pluralized names.
Если приложение зависело от прежних singular inferred names для morph pivot tables и использовало custom pivot classes, явно определите table name на pivot model.
Сериализация коллекций моделей восстанавливает eager-loaded relations
Вероятность влияния: низкая
Когда коллекции Eloquent models сериализуются и восстанавливаются, например в queued jobs, eager-loaded relations теперь восстанавливаются для models коллекции.
Если ваш код зависел от отсутствия relations после deserialization, эту логику может потребоваться изменить.
HTTP Client
Signatures Response::throw и throwIf в HTTP Client
Вероятность влияния: очень низкая
Методы response HTTP client теперь объявляют callback parameters в method signatures:
public function throw($callback = null);
public function throwIf($condition, $callback = null);
Если вы переопределяете эти методы в custom response classes, убедитесь, что method signatures совместимы.
Notifications
Default subject письма сброса пароля
Вероятность влияния: очень низкая
Default subject письма сброса пароля Laravel изменился:
// Laravel <= 12.x
Reset Password Notification
// Laravel >= 13.x
Reset your password
Если ваши tests, assertions или translation overrides зависят от прежней строки по умолчанию, обновите их.
Queued notifications и отсутствующие models
Вероятность влияния: очень низкая
Queued notifications теперь учитывают атрибут #[DeleteWhenMissingModels] и свойство $deleteWhenMissingModels, определенные на notification class.
В предыдущих версиях missing models могли все еще приводить к сбою queued notification jobs в случаях, когда вы ожидали их удаления.
Queue
Exception payload события JobAttempted
Вероятность влияния: низкая
Событие Illuminate\Queue\Events\JobAttempted теперь предоставляет exception object или null через $exception, заменяя прежнее boolean-свойство $exceptionOccurred:
// Laravel <= 12.x
$event->exceptionOccurred;
// Laravel >= 13.x
$event->exception;
Если вы слушаете это событие, обновите код слушателя.
Переименование свойства события QueueBusy
Вероятность влияния: низкая
Свойство $connection события Illuminate\Queue\Events\QueueBusy переименовано в $connectionName для согласованности с другими событиями очереди.
Если ваши слушатели обращаются к $connection, обновите их на $connectionName.
Добавления методов в контракт Queue
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Queue\Queue теперь включает методы проверки размера очереди, которые раньше были объявлены только в docblocks.
Если вы поддерживаете пользовательские реализации драйвера очереди для этого контракта, добавьте реализации для:
pendingSizedelayedSizereservedSizecreationTimeOfOldestPendingJob
Маршрутизация
Приоритет регистрации domain routes
Вероятность влияния: низкая
Routes с явно указанным domain теперь имеют приоритет над non-domain routes при route matching.
Это позволяет catch-all subdomain routes вести себя согласованно, даже если non-domain routes зарегистрированы раньше. Если ваше приложение зависело от прежнего registration precedence между domain и non-domain routes, проверьте route matching behavior.
Scheduling
Timing регистрации withScheduling
Вероятность влияния: очень низкая
Schedules, зарегистрированные через ApplicationBuilder::withScheduling(), теперь откладываются до момента разрешения Schedule.
Если ваше приложение зависело от немедленного timing регистрации schedule во время bootstrap, эту логику может потребоваться изменить.
Security
Защита от подделки запросов
Вероятность влияния: высокая
CSRF middleware Laravel переименован с VerifyCsrfToken в PreventRequestForgery и теперь включает проверку origin запроса с помощью заголовка Sec-Fetch-Site.
VerifyCsrfToken и ValidateCsrfToken остаются устаревшими псевдонимами, но прямые ссылки следует обновить на PreventRequestForgery, особенно при исключении middleware в тестах или определениях маршрутов:
use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
// Laravel <= 12.x
->withoutMiddleware([VerifyCsrfToken::class]);
// Laravel >= 13.x
->withoutMiddleware([PreventRequestForgery::class]);
API конфигурации middleware теперь также предоставляет preventRequestForgery(...).
Support
Binding callback для extend в manager
Вероятность влияния: низкая
Custom driver closures, зарегистрированные через manager methods extend, теперь bound к manager instance.
Если раньше вы полагались на другой bound object, например service provider instance, как $this внутри этих callbacks, перенесите такие значения в closure captures через use (...).
Сброс Str factories между тестами
Вероятность влияния: низкая
Laravel теперь сбрасывает custom Str factories во время test teardown.
Если ваши tests зависели от того, что custom UUID / ULID / random string factories сохраняются между test methods, задавайте их в каждом соответствующем test или setup hook.
Js::from по умолчанию использует unescaped Unicode
Вероятность влияния: очень низкая
Illuminate\Support\Js::from теперь по умолчанию использует JSON_UNESCAPED_UNICODE.
Если ваши tests или frontend output comparisons зависели от escaped Unicode sequences, например \u00e8, обновите expectations.
Utilities
Symfony PHP 8.5 Polyfill и конфликты global functions
Вероятность влияния: низкая
Laravel 13 добавляет dependency symfony/polyfill-php85. На версиях PHP ниже 8.5 этот polyfill определяет global functions, такие как array_first() и array_last(), если они не были определены ранее во время bootstrap.
Эти функции могут конфликтовать с legacy helper packages вроде laravel/helpers или custom global helpers с такими же именами. Например, исторический helper array_first() принимал callback, чтобы вернуть первый подходящий element, тогда как polyfilled version возвращает только первый element массива.
Чтобы избежать конфликтов и обеспечить согласованное поведение между версиями PHP, предпочитайте методы Illuminate\Support\Arr:
use Illuminate\Support\Arr;
Arr::first($array, function ($value) {
return /* condition */;
});
Представления
Имена Bootstrap-представлений для пагинации
Вероятность влияния: низкая
Внутренние имена представлений пагинации для значений Bootstrap 3 по умолчанию теперь явные:
// Laravel <= 12.x
pagination::default
pagination::simple-default
// Laravel >= 13.x
pagination::bootstrap-3
pagination::simple-bootstrap-3
Если ваше приложение напрямую ссылается на старые имена представлений пагинации, обновите эти ссылки.
Разное
Мы также рекомендуем просмотреть изменения в GitHub-репозитории laravel/laravel. Хотя многие из этих изменений не обязательны, возможно, вы захотите синхронизировать эти файлы с вашим приложением. Некоторые изменения будут описаны в этом руководстве по обновлению, но другие, например изменения файлов конфигурации или комментариев, не будут. Вы можете легко посмотреть изменения с помощью инструмента сравнения GitHub и выбрать, какие обновления важны для вас.