| git | 080853d694311a6d78ae0b33995f74abf9f355e5 |
|---|
- Префиксы кеша и имена session cookies
- Сериализация коллекций моделей восстанавливает жадно загруженные связи
Container::callи значения nullable-классов по умолчанию- Приоритет регистрации доменных маршрутов
- Payload исключения события
JobAttempted - Привязка callback-функции для
extendв менеджере - Запросы MySQL
DELETEсJOIN,ORDER BYиLIMIT - Имена Bootstrap-представлений для пагинации
- Генерация имени полиморфной сводной таблицы
- Переименование свойства события
QueueBusy - Конфигурация
serializationсессии - Сброс factories
Strмежду тестами
Note
Мы стараемся документировать все возможные критические изменения. Поскольку часть этих изменений находится в редко используемых областях фреймворка, только некоторые из них могут затронуть ваше приложение. Чтобы сэкономить время, можно использовать Shift. Shift - поддерживаемый сообществом сервис, который автоматизирует обновления Laravel.
Вы можете автоматизировать обновление с помощью 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.json:
laravel/frameworkдо^13.0laravel/boostдо^2.0laravel/tinkerдо^3.0phpunit/phpunitдо^12.0pestphp/pestдо^4.0
Если вы используете 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 до последнего релиза.
Вероятность влияния: низкая
Префиксы кеша и ключей 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 в окружении.
Вероятность влияния: очень низкая
Контракты кеша теперь включают метод touch для продления TTL элементов. Если вы поддерживаете пользовательские реализации хранилища кеша, добавьте этот метод:
// Illuminate\Contracts\Cache\Store
public function touch($key, $seconds);Вероятность влияния: средняя
Конфигурация cache приложения по умолчанию теперь включает опцию serializable_classes, установленную в false. Это усиливает безопасность десериализации кеша и помогает предотвратить цепочки атак через PHP-десериализацию, если APP_KEY вашего приложения утечет. Если приложение намеренно хранит PHP-объекты в кеше, явно перечислите классы, которые можно десериализовать:
'serializable_classes' => [
App\Data\CachedDashboardStats::class,
App\Support\CachedPricingSnapshot::class,
],Если приложение раньше полагалось на десериализацию произвольных кешированных объектов, нужно перенести такой код на явные списки разрешенных классов или на payload кеша без объектов, например массивы.
Вероятность влияния: низкая
Container::call теперь учитывает значения по умолчанию для nullable-параметров классов, когда привязка отсутствует, что соответствует поведению внедрения зависимостей через конструктор, представленному в Laravel 12:
$container->call(function (?Carbon $date = null) {
return $date;
});
// Laravel <= 12.x: Carbon instance
// Laravel >= 13.x: nullЕсли ваша логика внедрения зависимостей при вызове метода зависела от прежнего поведения, ее может потребоваться обновить.
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Bus\Dispatcher теперь включает метод dispatchAfterResponse($command, $handler = null).
Если вы поддерживаете пользовательскую реализацию диспетчера, добавьте этот метод в ваш класс.
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Routing\ResponseFactory теперь включает сигнатуру eventStream.
Если вы поддерживаете пользовательскую реализацию этого контракта, добавьте этот метод.
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Auth\MustVerifyEmail теперь включает markEmailAsUnverified().
Если у вас есть пользовательская реализация этого контракта, добавьте этот метод для совместимости.
Вероятность влияния: средняя
Laravel теперь проверяет, что caller передал непустое значение uniqueBy, и выбрасывает InvalidArgumentException вместо генерации некорректного SQL.
Хотя database drivers MariaDB и MySQL игнорируют значение uniqueBy и всегда используют primary и unique indexes таблицы для обнаружения существующих записей, validation все равно применяется. Если uniqueBy пустой, будет выброшен InvalidArgumentException.
Вероятность влияния: низкая
Laravel теперь компилирует полные запросы DELETE ... JOIN, включая ORDER BY и LIMIT, для грамматики MySQL.
В предыдущих версиях выражения ORDER BY / LIMIT могли молча игнорироваться для удалений с JOIN. В Laravel 13 эти выражения включаются в сгенерированный SQL. В результате движки баз данных, которые не поддерживают такой синтаксис, например стандартные варианты MySQL / MariaDB, теперь могут выбросить QueryException вместо выполнения неограниченного удаления.
Вероятность влияния: очень низкая
Создание нового 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.
Вероятность влияния: низкая
Когда 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.
Вероятность влияния: низкая
Когда коллекции Eloquent models сериализуются и восстанавливаются, например в queued jobs, eager-loaded relations теперь восстанавливаются для models коллекции.
Если ваш код зависел от отсутствия relations после deserialization, эту логику может потребоваться изменить.
Вероятность влияния: очень низкая
Методы response HTTP client теперь объявляют callback parameters в method signatures:
public function throw($callback = null);
public function throwIf($condition, $callback = null);Если вы переопределяете эти методы в custom response classes, убедитесь, что method signatures совместимы.
Вероятность влияния: очень низкая
Default subject письма сброса пароля Laravel изменился:
// Laravel <= 12.x
Reset Password Notification
// Laravel >= 13.x
Reset your password
Если ваши tests, assertions или translation overrides зависят от прежней строки по умолчанию, обновите их.
Вероятность влияния: очень низкая
Queued notifications теперь учитывают атрибут #[DeleteWhenMissingModels] и свойство $deleteWhenMissingModels, определенные на notification class.
В предыдущих версиях missing models могли все еще приводить к сбою queued notification jobs в случаях, когда вы ожидали их удаления.
Вероятность влияния: низкая
Событие Illuminate\Queue\Events\JobAttempted теперь предоставляет exception object или null через $exception, заменяя прежнее boolean-свойство $exceptionOccurred:
// Laravel <= 12.x
$event->exceptionOccurred;
// Laravel >= 13.x
$event->exception;Если вы слушаете это событие, обновите код слушателя.
Вероятность влияния: низкая
Свойство $connection события Illuminate\Queue\Events\QueueBusy переименовано в $connectionName для согласованности с другими событиями очереди.
Если ваши слушатели обращаются к $connection, обновите их на $connectionName.
Вероятность влияния: очень низкая
Контракт Illuminate\Contracts\Queue\Queue теперь включает методы проверки размера очереди, которые раньше были объявлены только в docblocks.
Если вы поддерживаете пользовательские реализации драйвера очереди для этого контракта, добавьте реализации для:
pendingSizedelayedSizereservedSizecreationTimeOfOldestPendingJob
Вероятность влияния: низкая
Routes с явно указанным domain теперь имеют приоритет над non-domain routes при route matching.
Это позволяет catch-all subdomain routes вести себя согласованно, даже если non-domain routes зарегистрированы раньше. Если ваше приложение зависело от прежнего registration precedence между domain и non-domain routes, проверьте route matching behavior.
Вероятность влияния: низкая
Чтобы снизить риск атак с использованием цепочек гаджетов десериализации PHP, стандартный каркас приложения теперь устанавливает для параметра сессии serialization значение json в файле config/session.php.
Если вы обновляете существующее приложение и синхронизируете его конфигурационные файлы с каркасом Laravel 13, изменение этого значения с php на json сделает недействительными все активные пользовательские сессии.
Чтобы сохранить активные сессии при обновлении, оставьте значение php. Однако, если приложение не хранит PHP-объекты в сессии и вы готовы потребовать от пользователей повторной аутентификации, для повышения безопасности рекомендуется изменить значение на json.
Вероятность влияния: очень низкая
Schedules, зарегистрированные через ApplicationBuilder::withScheduling(), теперь откладываются до момента разрешения Schedule.
Если ваше приложение зависело от немедленного timing регистрации schedule во время bootstrap, эту логику может потребоваться изменить.
Вероятность влияния: высокая
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(...).
Вероятность влияния: низкая
Custom driver closures, зарегистрированные через manager methods extend, теперь bound к manager instance.
Если раньше вы полагались на другой bound object, например service provider instance, как $this внутри этих callbacks, перенесите такие значения в closure captures через use (...).
Вероятность влияния: низкая
Laravel теперь сбрасывает custom Str factories во время test teardown.
Если ваши tests зависели от того, что custom UUID / ULID / random string factories сохраняются между test methods, задавайте их в каждом соответствующем test или setup hook.
Вероятность влияния: очень низкая
Illuminate\Support\Js::from теперь по умолчанию использует JSON_UNESCAPED_UNICODE.
Если ваши tests или frontend output comparisons зависели от escaped Unicode sequences, например \u00e8, обновите expectations.
Вероятность влияния: низкая
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 3 по умолчанию теперь явные:
// Laravel <= 12.x
pagination::default
pagination::simple-default
// Laravel >= 13.x
pagination::bootstrap-3
pagination::simple-bootstrap-3
Если ваше приложение напрямую ссылается на старые имена представлений пагинации, обновите эти ссылки.
Мы также рекомендуем просмотреть изменения в GitHub-репозитории laravel/laravel. Хотя многие из них необязательны, возможно, вы захотите синхронизировать соответствующие файлы с приложением. В этом руководстве описаны не все изменения, например правки файлов конфигурации или комментариев. Полный список можно изучить с помощью инструмента сравнения GitHub и выбрать нужные обновления.