Версия фреймворка: 8.x 5.4 4.2
Это скорректированный автоматический перевод, сделанный при помощи google translate.

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

Изменения, оказывающие большое влияние

Изменения со средней степенью воздействия

Обновление с 7.x версии до 8.0

Приблизительное время обновления: 15 минут

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

Требование PHP 7.3.0

Вероятность воздействия: средняя

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

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

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

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

Следующие сторонние пакеты имеют новые основные выпуски для поддержки 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]);

База данных

Пространства имен наполнителей и фабрик

Вероятность воздействия: высокая

Наполнители и фабрики теперь имеют пространство имен. Чтобы учесть эти изменения, добавьте пространство имен Database\Seeders в ваши классы наполнителей. Кроме того, имеющийся каталог database/seeds должен быть переименован в database/seeders:

<?php

namespace Database\Seeders;

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

class DatabaseSeeder extends Seeder
{
    /**
     * Заполнить базу данных приложения.
     *
     * @return void
     */
    public function run()
    {
        ...
    }
}

Если вы решите использовать пакет laravel/legacy-factories, то никаких изменений в классах ваших фабрик не требуется. Однако, если вы обновляете свои фабрики, вы должны добавить к этим классам пространство имен Database\Factories.

Затем в вашем файле composer.json удалите блок classmap из раздела autoload и добавьте новые сопоставления каталогов классов с пространством имен:

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

Eloquent

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

Вероятность воздействия: высокая

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

composer require laravel/legacy-factories

Интерфейс Castable

Вероятность воздействия: низкая

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

public static function castUsing(array $arguments);

События Increment / Decrement

Вероятность воздействия: низкая

События модели, связанные с «обновлением» и «сохранением», теперь будут вызываться при выполнении методов increment или decrement экземпляров модели Eloquent.

События

Класс EventServiceProvider

Вероятность воздействия: низкая

Если ваш класс App\Providers\EventServiceProvider содержит метод register, то вы должны убедиться, что вы вызываете parent::register в начале этого метода. В противном случае события вашего приложения не будут зарегистрированы.

Контракт Dispatcher

Вероятность воздействия: низкая

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

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

Фреймворк

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

Вероятность воздействия: необязательно

Режим обслуживания был улучшен в Laravel 8.x. Теперь поддерживается предварительный рендеринг шаблона режима обслуживания, что исключает вероятность того, что конечные пользователи столкнутся с ошибками в режиме обслуживания. Однако для поддержки этого в ваш файл public/index.php необходимо добавить следующие строки. Эти строки следует разместить непосредственно под существующим определением константы LARAVEL_START:

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

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

Параметр php artisan down --message

Вероятность воздействия: средняя

Параметр --message команды php artisan down была удалена. В качестве альтернативы рассмотрите возможность предварительного рендеринга шаблонов в режиме обслуживания с желаемым сообщением.

Параметр php artisan serve --no-reload

Вероятность воздействия: низкая

В команде php artisan serve добавлен параметр --no-reload. Это даст указание встроенному серверу не перезагружаться при обнаружении изменений файла окружения. Эта опция в первую очередь полезна при запуске тестов Laravel Dusk в среде CI (непрерывной интеграции).

Свойство $app Менеджера

Вероятность воздействия: низкая

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

Помощник elixir

Вероятность воздействия: низкая

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

Почта

Метод sendNow

Вероятность воздействия: низкая

Ранее устаревший метод sendNow был удален. Вместо этого используйте метод send.

Постраничная навигация

Пагинация по умолчанию

Вероятность воздействия: высокая

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

use Illuminate\Pagination\Paginator;

Paginator::useBootstrap();

Очереди

Метод retryAfter

Вероятность воздействия: высокая

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

Свойство timeoutAt

Вероятность воздействия: высокая

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

Методы allOnQueue() / allOnConnection()

Вероятность воздействия: высокая

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

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

Обратите внимание, что это изменение влияет только на код, использующий метод withChain. В то время как методы allOnQueue() и allOnConnection() по-прежнему доступны при использовании глобального помощника dispatch().

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

Вероятность воздействия: необязательно

Если вы планируете использовать функционал пакетной обработки заданий Laravel 8.x, то таблица 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 в конфигурационном файле config/queue.php должен быть изменен на database-uuids.

Кроме того, вы можете сгенерировать UUID для существующих невыполненных заданий:

DB::table('failed_jobs')->whereNull('uuid')->cursor()->each(function ($job) {
    DB::table('failed_jobs')
        ->where('id', $job->id)
        ->update(['uuid' => (string) Illuminate\Support\Str::uuid()]);
});

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

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

Вероятность воздействия: необязательно

В предыдущих выпусках Laravel класс RouteServiceProvider содержал свойство $namespace со значением App\Http\Controllers. Это значение этого свойства использовалось для объявлений автоматического префикса маршрута контроллера и генерации URL маршрута контроллера, например, при вызове помощника 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 с его предыдущим значением. Однако, если вы обновите свое приложение, создав новый проект Laravel, то это изменение может стать критическим.

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

class RouteServiceProvider extends ServiceProvider
{
    /**
     * Путь к «домашнему» маршруту вашего приложения.
     *
     * Используется аутентификацией Laravel для перенаправления пользователей после входа в систему.
     *
     * @var string
     */
    public const HOME = '/home';

    /**
     * Если указано, это пространство имен автоматически применяется к маршрутам вашего контроллера.
     *
     * Кроме того, оно устанавливается как корневое пространство имен генератора URL.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * Определить связывание модели и маршрута, фильтры шаблонов и т.д.
     *
     * @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'));
        });
    }

    /**
     * Настроить ограничения запросов для приложения.
     *
     * @return void
     */
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
        });
    }
}

Планирование задач

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

Вероятность воздействия: низкая

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

Сессия

Контракт Session

Вероятность воздействия: низкая

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

/**
 * Получите значение переданного ключа и удалить его.
 *
 * @param  string  $key
 * @param  mixed  $default
 * @return mixed
 */
public function pull($key, $default = null);

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

Метод decodeResponseJson

Вероятность воздействия: низкая

Метод decodeResponseJson, принадлежащий классу Illuminate\Testing\TestResponse, больше не принимает никаких аргументов. Пожалуйста, подумайте об использовании вместо этого метода json.

Метод assertExactJson

Вероятность воздействия: средняя

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

Валидация

Соединения для правил, использующих БД

Вероятность воздействия: низкая

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

Разное

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