Поддержите проект сделав пожертвование.
Будьте в курсе последних новостей!
Будьте в курсе последних новостей!

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

Вы просматриваете документ для прошлой версии.
Рассмотрите возможность обновления вашего проекта до актуальной версии 10.x. Почему это важно?

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

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

Обновление с 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($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
    require $maintenance;
}

Параметр 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 и выбрать, какие обновления важны для вас.