Skip to content
Icon

ПРЕДУПРЕЖДЕНИЕ Вы просматриваете документацию к старой версии Laravel. Рассмотрите возможность обновления Вашего проекта до Laravel 9.x.

Разработка пакета

Введение

Пакеты — это основной способ добавления функциональности в Laravel. Пакеты могут быть чем угодно: от отличного способа работы с датами, такими как Carbon, до пакетов, позволяющих связывать файлы с моделями Eloquent, такими как Spatie Laravel Media Library.

Существуют разные типы пакетов. Некоторые пакеты являются автономными, то есть они работают с любой инфраструктурой PHP. Carbon и PHPUnit являются примерами автономных пакетов. Любой из этих пакетов можно использовать с Laravel, потребовав их в вашем файле composer.json.

С другой стороны, другие пакеты специально предназначены для использования с Laravel. Эти пакеты могут иметь маршруты, контроллеры, представления и конфигурацию, специально предназначенные для улучшения приложения Laravel. Это руководство в первую очередь охватывает разработку тех пакетов, которые специфичны для Laravel.

Примечание о фасадах

При написании приложения Laravel, как правило, не имеет значения, используете ли вы контракты или фасады, поскольку оба обеспечивают практически одинаковые уровни тестируемости. Однако при написании пакетов ваш пакет обычно не будет иметь доступа ко всем помощникам тестирования Laravel. Если вы хотите иметь возможность писать тесты пакетов, как если бы пакет был установлен внутри типичного приложения Laravel, вы можете использовать пакет Orchestral Testbench.

Обнаружение пакета

В файле конфигурации config/app.php приложения Laravel параметр providers определяет список поставщиков услуг, которые должны быть загружены Laravel. Когда кто-то устанавливает ваш пакет, вы, как правило, хотите, чтобы ваш поставщик услуг был включен в этот список. Вместо того, чтобы требовать, чтобы пользователи вручную добавляли вашего поставщика услуг в список, вы можете определить поставщика в разделе extra файла composer.json вашего пакета. Помимо поставщиков услуг, вы также можете перечислить любые [фасады]](/docs/{{version}}/facades), которые вы хотели бы зарегистрировать:

"extra": {
"laravel": {
"providers": [
"Barryvdh\\Debugbar\\ServiceProvider"
],
"aliases": {
"Debugbar": "Barryvdh\\Debugbar\\Facade"
}
}
},

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

Отказ от обнаружения пакетов

Если вы являетесь потребителем пакета и хотели бы отключить обнаружение пакета для пакета, вы можете указать имя пакета в разделе extra файла composer.json вашего приложения:

"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar"
]
}
},

Вы можете отключить обнаружение пакетов для всех пакетов, используя символ * внутри директивы dont-discover вашего приложения:

"extra": {
"laravel": {
"dont-discover": [
"*"
]
}
},

Сервис провайдеры

Поставщики услуг — это точка соединения между вашим пакетом и Laravel. Поставщик услуг отвечает за привязку вещей к сервисному контейнеру и сообщает Laravel, где загружать ресурсы пакета, такие как представления, файлы конфигурации и локализации.

Поставщик услуг расширяет класс Illuminate\Support\ServiceProvider и содержит два метода: register и boot. Базовый класс ServiceProvider находится в пакете Composer illuminate/support, который вы должны добавить в зависимости вашего собственного пакета. Чтобы узнать больше о структуре и назначении поставщиков услуг, ознакомьтесь с их документацией.

Ресурсы

Конфигурация

Как правило, вам потребуется опубликовать файл конфигурации вашего пакета в каталоге приложения config. Это позволит пользователям вашего пакета легко переопределить параметры конфигурации по умолчанию. Чтобы разрешить публикацию файлов конфигурации, вызовите метод publishes из метода boot вашего поставщика услуг:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../config/courier.php' => config_path('courier.php'),
]);
}

Теперь, когда пользователи вашего пакета выполнят команду Laravel vendor:publish, ваш файл будет скопирован в указанное место для публикации. После того, как ваша конфигурация была опубликована, к ее значениям можно получить доступ, как и к любому другому файлу конфигурации:

$value = config('courier.option');

{note} Вы не должны определять замыкания в своих файлах конфигурации. Они не могут быть правильно сериализованы, когда пользователи выполняют Artisan-команду config:cache.

Конфигурация пакета по умолчанию

Вы также можете объединить свой собственный файл конфигурации пакета с опубликованной копией приложения. Это позволит вашим пользователям определять только те параметры, которые они действительно хотят переопределить в опубликованной копии файла конфигурации. Чтобы объединить значения файла конфигурации, используйте метод mergeConfigFrom в методе register вашего поставщика услуг.

Метод mergeConfigFrom принимает путь к файлу конфигурации вашего пакета в качестве первого аргумента и имя копии файла конфигурации приложения в качестве второго аргумента:

/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(
__DIR__.'/../config/courier.php', 'courier'
);
}

{note} Этот метод объединяет только первый уровень массива конфигурации. Если ваши пользователи частично определяют многомерный массив конфигурации, отсутствующие параметры не будут объединены.

Маршруты

Если ваш пакет содержит маршруты, вы можете загрузить их с помощью метода loadRoutesFrom. Этот метод автоматически определит, кэшированы ли маршруты приложения, и не загрузит ваш файл маршрутов, если маршруты уже кэшированы:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->loadRoutesFrom(__DIR__.'/../routes/web.php');
}

Миграции

Если ваш пакет содержит миграции базы данных, вы можете использовать метод loadMigrationsFrom, чтобы сообщить Laravel, как их загружать. Метод loadMigrationsFrom принимает путь к миграциям вашего пакета в качестве единственного аргумента:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->loadMigrationsFrom(__DIR__.'/../database/migrations');
}

Как только миграции вашего пакета будут зарегистрированы, они будут автоматически запущены при выполнении команды php artisan migrate. Вам не нужно экспортировать их в каталог database/migrations приложения.

Переводы

Если ваш пакет содержит файлы перевода, вы можете использовать метод loadTranslationsFrom, чтобы сообщить Laravel, как их загружать. Например, если ваш пакет называется courier, вы должны добавить следующее к методу boot поставщика услуг:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'courier');
}

На переводы пакетов ссылаются с использованием синтаксического соглашения package::file.line. Таким образом, вы можете загрузить строку приветствия welcome пакета courier из файла messages следующим образом:

echo trans('courier::messages.welcome');

Публикация переводов

Если вы хотите опубликовать переводы вашего пакета в каталог приложения resources/lang/vendor, вы можете использовать метод publishes поставщика услуг. Метод publishes принимает массив путей пакетов и их желаемых мест публикации. Например, чтобы опубликовать файлы перевода для пакета courier, вы можете сделать следующее:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'courier');
 
$this->publishes([
__DIR__.'/../resources/lang' => resource_path('lang/vendor/courier'),
]);
}

Теперь, когда пользователи вашего пакета выполняют Artisan-команду Laravel vendor:publish, переводы вашего пакета будут опубликованы в указанном месте публикации.

Представления

Чтобы зарегистрировать представления вашего пакета в Laravel, вам нужно сообщить Laravel, где находятся представления. Вы можете сделать это, используя метод loadViewsFrom поставщика услуг. Метод loadViewsFrom принимает два аргумента: путь к вашим шаблонам представлений и имя вашего пакета. Например, если имя вашего пакета courier, вы должны добавить следующее к методу boot вашего поставщика услуг:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
}

На представления пакетов ссылаются с использованием синтаксического соглашения package::view. Таким образом, после того, как ваш путь просмотра зарегистрирован у поставщика услуг, вы можете загрузить представление dashboard из пакета courier следующим образом:

Route::get('/dashboard', function () {
return view('courier::dashboard');
});

Переопределение представлений пакета

Когда вы используете метод loadViewsFrom, Laravel фактически регистрирует два местоположения для ваших представлений: каталог resources/views/vendor приложения и указанный вами каталог. Таким образом, используя в качестве примера пакет courier, Laravel сначала проверит, была ли разработчиком размещена пользовательская версия представления в каталоге resources/views/vendor/courier. Затем, если представление не было настроено, Laravel будет искать каталог представления пакета, указанный вами в вызове loadViewsFrom. Это позволяет пользователям пакета легко настраивать/переопределять представления вашего пакета.

Публикация просмотров

Если вы хотите сделать свои представления доступными для публикации в каталоге resources/views/vendor приложения, вы можете использовать метод publishes поставщика услуг. Метод publishes принимает массив путей просмотра пакетов и их желаемых мест публикации:

/**
* Bootstrap the package services.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/../resources/views', 'courier');
 
$this->publishes([
__DIR__.'/../resources/views' => resource_path('views/vendor/courier'),
]);
}

Теперь, когда пользователи вашего пакета выполняют Artisan-команду Laravel vendor:publish, представления вашего пакета будут скопированы в указанное место публикации.

Представление компонентов

Если ваш пакет содержит представление компонентов, вы можете использовать метод loadViewComponentsAs, чтобы сообщить Laravel, как их загружать. Метод loadViewComponentsAs принимает два аргумента: префикс тега для компонентов представления и массив имен классов компонентов представления. Например, если префикс вашего пакета — courier, и у вас есть компоненты представления Alert и Button, вы должны добавить следующее к методу boot вашего поставщика услуг:

use Courier\Components\Alert;
use Courier\Components\Button;
 
/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->loadViewComponentsAs('courier', [
Alert::class,
Button::class,
]);
}

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

<x-courier-alert />
 
<x-courier-button />

Анонимные компоненты

Если ваш пакет содержит анонимные компоненты, они должны быть помещены в каталог components каталога "views" вашего пакета (как указано в loadViewsFrom). Затем вы можете отображать их, добавляя к имени компонента префикс пространства имен представления пакета:

<x-courier::alert />

Команды

Чтобы зарегистрировать Artisan-команды вашего пакета в Laravel, вы можете использовать метод commands. Этот метод ожидает массив имен классов команд. После регистрации команд вы можете выполнять их с помощью Artisan CLI:

use Courier\Console\Commands\InstallCommand;
use Courier\Console\Commands\NetworkCommand;
 
/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
$this->commands([
InstallCommand::class,
NetworkCommand::class,
]);
}
}

Публичные асеты

В вашем пакете могут быть активы, такие как JavaScript, CSS и изображения. Чтобы опубликовать эти активы в public каталоге приложения, используйте метод поставщика услуг publishes. В этом примере мы также добавим тег группы ресурсов public, который можно использовать для простой публикации групп связанных ресурсов:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../public' => public_path('vendor/courier'),
], 'public');
}

Теперь, когда пользователи вашего пакета выполнят команду vendor:publish, ваши активы будут скопированы в указанное место для публикации. Поскольку пользователям обычно приходится перезаписывать активы каждый раз при обновлении пакета, вы можете использовать флаг --force:

php artisan vendor:publish --tag=public --force

Публикация файловых групп

Вы можете публиковать группы активов и ресурсов пакета отдельно. Например, вы можете разрешить своим пользователям публиковать файлы конфигурации вашего пакета без необходимости публиковать активы вашего пакета. Вы можете сделать это, «пометив» их при вызове метода publishes от поставщика услуг пакета. Например, давайте используем теги для определения двух групп публикации для пакета courier (courier-config и courier-migrations) в методе boot поставщика услуг пакета:

/**
* Bootstrap any package services.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../config/package.php' => config_path('package.php')
], 'courier-config');
 
$this->publishes([
__DIR__.'/../database/migrations/' => database_path('migrations')
], 'courier-migrations');
}

Теперь ваши пользователи могут публиковать эти группы отдельно, ссылаясь на их тег при выполнении команды vendor:publish:

php artisan vendor:publish --tag=courier-config