Skip to main content

什么是包

在 Laravel 中,包是为应用程序添加功能的 Composer 包。包大致分为两类:
  • 独立包 — 不依赖于 Laravel 的通用 PHP 库(例如:Carbon、Pest)
  • Laravel 包 — 包含路由、控制器、视图、配置等与 Laravel 集成的功能包
本指南将介绍后者,即 Laravel 专用包的开发。开发包需要深入理解 Laravel 的内部结构,包括服务提供者、门面以及配置文件的发布等。
编写包的测试时,可以使用 Orchestra Testbench。它可以像编写普通 Laravel 应用一样编写包的测试。

包的自动发现

Laravel 在安装包时,会读取 composer.json 中的 extra.laravel 部分,并自动注册服务提供者和门面。
添加此配置后,用户无需手动编辑 bootstrap/providers.php,包也会被自动加载。
关于该自动发现的实现方式,以及缓存何时会被重建,可参阅包自动发现的内部结构

禁用自动发现

如果用户希望禁用特定包的自动发现,可以在应用程序的 composer.json 中进行设置。

服务提供者的作用

服务提供者是包的入口。将视图、配置、迁移、路由等资源注册到 Laravel 的处理都集中在这里。 服务提供者继承 Illuminate\Support\ServiceProvider,并包含 registerboot 两个方法。
请勿在 register 方法内注册事件监听器、路由、视图等。因为此时可能会误用尚未加载的其他服务提供者提供的服务。除绑定之外的处理,务必都在 boot 方法中进行。

配置文件的发布

publishes() — 发布文件

boot 方法中调用 publishes(),用户就可以使用 vendor:publish 命令将配置文件复制到自己的应用中。
发布后,可以像访问普通 config 一样获取配置值。

mergeConfigFrom() — 与默认值合并

register 方法中使用 mergeConfigFrom(),即使用户未发布配置文件,也会使用包的默认值。
mergeConfigFrom() 不会深层合并嵌套数组。对于包含多维数组的配置,如果用户只定义了一部分,可能会导致其余选项未被合并。

使用标签划分发布组

publishes() 的第二个参数中指定标签,用户就可以选择性地发布所需的资源。

注册路由

使用 loadRoutesFrom() 加载路由文件。当应用的路由缓存有效时,它会被自动跳过。
在路由文件中指定包的控制器。

迁移的发布

使用 publishesMigrations() 可以发布迁移文件。发布时 Laravel 会自动更新时间戳。

视图的发布

loadViewsFrom() — 注册视图

使用 loadViewsFrom() 注册视图目录。通过第二个参数指定的命名空间,以 package::view 的形式引用视图。
注册后,视图通过包命名空间引用。
Laravel 会从两处查找视图。首先检查应用的 resources/views/vendor/courier 目录,若不存在则使用包的视图目录。这样用户就可以自定义视图。

发布视图

注册 Blade 组件

如果包中包含组件,可以在 boot 方法中注册。
也可以使用组件命名空间进行批量注册。

翻译文件的发布

使用 loadTranslationsFrom() 注册翻译文件。翻译通过 package::file.key 的形式引用。
使用 JSON 翻译文件时,请使用 loadJsonTranslationsFrom()

注册命令

包的 Artisan 命令通过 commands() 方法注册。通常只在控制台环境下注册。

集成到 optimize 命令

如果包拥有自己的缓存,可以通过 optimizes() 方法集成到 php artisan optimizephp artisan optimize:clear

about 命令添加信息

要向 php artisan about 的输出中添加包信息,可使用 AboutCommand::add()

创建门面

使用门面可以将服务容器的绑定作为静态方法调用。
1

创建服务类

2

创建门面类

继承 Illuminate\Support\Facades\Facade,并在 getFacadeAccessor() 中返回服务容器的绑定键。
3

在服务提供者中绑定

4

在 composer.json 中注册

为门面的方法添加 PHPDoc 的 @method 注解,可以让 IDE 自动补全生效。

DeferrableProvider — 实现延迟加载

对于只向服务容器进行绑定的提供者,可以通过实现 DeferrableProvider 接口来实现延迟加载。由于在服务实际被需要之前提供者不会被加载,因此可以提升应用的性能。
Laravel 会编译并保存延迟提供者所提供的服务列表。只有在解析 provides() 中列举的服务时,提供者才会被加载。
对于需要注册资源(视图、路由、事件监听器等)的提供者,请勿使用 DeferrableProvider。若被延迟加载,这些资源将不会被注册。

包的测试

单独测试包时可使用 Orchestra Testbench。它可以让你像在普通 Laravel 应用中一样编写包的测试。
在测试用例中重写 getPackageProviders() 以注册包的服务提供者。

发布到 Composer

以下是将包发布到 Packagist 的最佳实践。 composer.json 的基本配置
通过依赖 illuminate/support,可以只将 Laravel 所需的组件纳入依赖,而不是整个 illuminate/framework。请保持包的依赖树尽可能精简。
目录结构示例

相关页面

服务提供者

了解服务提供者的 registerboot 方法,以及延迟提供者的详细信息。

版本兼容性管理

介绍应对 Laravel 与 PHP 大版本升级的策略,以及 GitHub Actions 的测试矩阵配置。
最后修改于 2026年8月2日