Руководство по обновлению до Laravel 8

Руководство по обновлению до Laravel 8

Мы постарались задокументировать все возможные критические изменения. Поскольку некоторые из них находятся в малоизвестных частях фреймворка, только часть этих изменений может повлиять на ваше приложение. Приблизительное время обновления: 15 минут.

Требуется PHP 7.3

Новая минимальная версия PHP теперь 7.3.0.

Обновление зависимостей

Обновите следующие зависимости в своем файле composer.json

  • laravel/framework до ^8.0
  • nunomaduro/collision до ^5.0
  • phpunit/phpunit  до  ^9.0
  • guzzlehttp/guzzle до ^7.0.1
  • facade/ignition до ^2.3.6

Следующие наши пакеты получили новую мажорную версию для поддержки Laravel 8. По возможности прочтите соответствующие руководства по их обновлению:

Laravel инсталлер обновлён и теперь поддерживает composer create-project и Laravel Jetstream. Инсталлер версии ниже чем 4.0 перестанет работать после октября 2020 года. Необходимо как можно скорее обновить его до версии ^4.0.

Не забудьте также проверить все сторонние пакеты, используемые в вашем приложении, и убедитесь, что они поддерживают Laravel 8.

Коллекции

Метод isset

Чтобы соответствовать типичному поведению PHP, метод offsetExists из Illuminate\Support\Collection был обновлён и теперь использует isset вместо array_key_exists. Это может привести к изменению поведения при работе с элементами коллекции, имеющими значение null:

$collection = collect([null]);

// Laravel 7.x - true
isset($collection[0]);

// Laravel 8.x - false
isset($collection[0]);

База данных

Пространства имен Seeder и Factory

Сидеры и фабрики теперь используют пространства имён. Добавьте пространство имен Database/Factories в классы фабрик и Database/Seeders в классы сидеров.

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        ...
    }
}

Предыдущий каталог database/seeds нужно переименовать в database/seeders.

В файле composer.json из секции autoload удалите блок classmap и добавьте новые классы:

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Database\\Factories\\": "database/factories/",
        "Database\\Seeders\\": "database/seeders/"
    }
},

Eloquent

Фабрики моделей

Фабрики моделей полностью переписаны для поддержки классов и несовместимы с фабриками Laravel 7. Однако, чтобы упростить процесс обновления, был создан пакет laravel/legacy-factories, чтобы вы могли продолжать использовать ваши уже существующие фабрики. Вы можете установить этот пакет через Composer:

composer require laravel/legacy-factories

Интерфейс Castable

Метод castUsing интерфейса Castable был обновлен и теперь он принимает массив аргументов. Если вы используете этот интерфейс, то вам следует обновить свой код:

public static function castUsing(array $arguments);

События инкремента/декремента

При выполнении методов инкремента или декремента на экземплярах Eloquent-модели теперь будут отправляться соответствующие события модели «update» и «save».

События

Контракт Dispatcher

Метод listen контракта Illuminate\Contracts\Events\Dispatcher был обновлен и теперь параметр $listener необязателен. Это изменение было внесено для поддержки автоматического определения обрабатываемых типов событий через рефлексию. Если вы реализуете этот интерфейс вручную, то вам следует соответствующим образом обновить свою реализацию:

public function listen($events, $listener = null);

Фреймворк

Обновления режима обслуживания

Режим обслуживания улучшен. Теперь поддерживается возможность заранее отрендерить шаблон режима обслуживания и конечные пользователи не столкнутся с возможными ошибками. Но для поддержки этого необходимо в ваш файл public/index.php добавить пару строк. Их следует разместить сразу под определением константы LARAVEL_START:

define('LARAVEL_START', microtime(true));

if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) {
    require __DIR__.'/../storage/framework/maintenance.php';
}

Свойства $app в Manager

Удалено устаревшее свойство $app класса Illuminate\Support\Manager. Если вы его использовали, то вместо этого работайте со свойством $container.

Хелпер elixir

Удалён устаревший хелпер elixir. Приложениям, всё ещё использующим этот метод, рекомендуется перейти на Laravel Mix.

Почта

Метод sendNow

Удалён устаревший метод sendNow. Используйте вместо него метод send.

Пагинация

Дефолтная пагинация

Пагинатор по умолчанию теперь использует фреймворк Tailwind CSS. Чтобы продолжать использовать Bootstrap, необходимо добавить вызов следующего метода в метод boot в AppServiceProvider:

use Illuminate\Pagination\Paginator;

Paginator::useBootstrap();

Очередь

Метод retryAfter

Для согласования с другими функциями Laravel, метод retryAfter и свойство retryAfter задач в очереди, почтовиков, уведомлений и слушателей были переименованы в backoff. Вам следует обновить названия этого метода/свойства в соответствующих классах вашего приложения.

Свойство timeoutAt

Свойство timeoutAt задач в очереди, уведомлений и слушателей было переименовано в retryUntil. Вам следует обновить название этого свойства в соответствующих классах вашего приложения.

Методы allOnQueue и allOnConnection

Методы allOnQueue() и allOnConnection(), используемые для цепочек задач, были удалены. Используйте вместо этого методы onQueue() и onConnection():

ProcessPodcast::withChain([
    new OptimizePodcast,
    new ReleasePodcast
])->onConnection('redis')->onQueue('podcasts')->dispatch();

Поддержка Пакетирования в таблице невыполненных задач

Если вы планируете использовать функцию пакетной обработки задач, то необходимо обновить таблицу failed_jobs. Во-первых, в неё нужно добавить новое поле uuid:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('failed_jobs', function (Blueprint $table) {
    $table->string('uuid')->after('id')->nullable()->unique();
});

Затем параметр failed.driver в конфигурационном файле queue должен быть обновлён до database-uuids.

Маршрутизация

Автоматический префикс пространства имен контроллера

В предыдущих версиях Laravel класс RouteServiceProvider содержал свойство $namespace имевшее значение App\Http\Controllers. Оно использовалось для автоматического задания префикса маршрута контроллеров, например, при вызове хелпера action.

В Laravel 8 это свойство по дефолту равно null. Это позволяет маршрутам вашего контроллера использовать стандартный синтаксис PHP, который позволяет во многих IDE переходить сразу к классу контроллера.

use App\Http\Controllers\UserController;

// Используем синтаксис PHP...
Route::get('/users', [UserController::class, 'index']);

// Используем строковый синтаксис...
Route::get('/users', 'App\Http\Controllers\UserController@index');

В большинстве случаев это не повлияет на обновляемые приложения, так как в вашем RouteServiceProvider $namespace будет установлен по старому. Однако, если вы обновляете своё приложение через создание нового проекта, то можете столкнуться с этой проблемой.

Если вы хотите продолжить использование автоматического префикса, то просто задайте $namespace в вашем RouteServiceProvider и обновите регистрацию маршрутов в методе boot для его использования:

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));
    });
}

Планировщик

Библиотека cron-expression

Зависимость dragonmantank/cron-expression от была обновлена ​​с 2.x до 3.x. Это не должно вызывать каких-либо критических изменений в вашем приложении, если вы не взаимодействуете с библиотекой напрямую. Если же работаете напрямую, то ознакомьтесь с изменениями в ней.

Сессии

Контракт Session

Контракт Illuminate\Contracts\Session\Session получил новый метод pull. Если вы реализуете этот контракт вручную, то вам следует обновить свой код:

/**
  * Get the value of a given key and then forget it.
  *
  * @param  string  $key
  * @param  mixed  $default
  * @return mixed
  */
 public function pull($key, $default = null);

Тестирование

Метод assertExactJson

Теперь метод assertExactJson требует, чтобы числовые ключи сравниваемых массивов совпадали и располагались в одном порядке. Если же вы хотите сравнить JSON с массивом, не требуя, чтобы массивы с числовыми ключами имели одинаковый порядок, вы можете использовать метод assertSimilarJson.

Валидация

Подключение базы данных

Правила unique и exists теперь будут соблюдать название указанного соединения (доступное через модельный метод getConnectionName) Eloquent-моделей при выполнении запросов.

Разное

Мы также рекомендуем вам ознакомиться с изменениями в репозитории laravel/laravel. Некоторые из них рассмотрены в этом руководстве по обновлению, но другие, например изменения конфигурационных файлов или комментарии — нет. Вы можете легко просмотреть все изменения с помощью GitHub-инструмента сравнения и выбрать, какие их них важны для вас.

update 11.09.2020: Добавлены разделы Маршрутизация, База данных. Обновлен раздел Очередь.

Автор: Laravel
Перевод: Алексей Широков

Наш Телеграм-канал — следите за новостями о Laravel.