首页 » 网站建设 » phplaravel容器技巧_ Laravel 56 文档 底层事理 做事容器

phplaravel容器技巧_ Laravel 56 文档 底层事理 做事容器

访客 2024-12-10 0

扫一扫用手机浏览

文章目录 [+]

让我们看一个大略的例子:

<?phpnamespace App\Http\Controllers;use App\User;use App\Repositories\UserRepository;use App\Http\Controllers\Controller;class UserController extends Controller{ / The user repository implementation. @var UserRepository / protected $users; / Create a new controller instance. @param UserRepository $users @return void / public function __construct(UserRepository $users) { $this->users = $users; } / Show the profile for the given user. @param int $id @return Response / public function show($id) { $user = $this->users->find($id); return view('user.profile', ['user' => $user]); }}

在本例中,UserController 须要从数据源获取用户,以是,我们注入了一个可以获取用户的做事 UserRepository,其扮演的角色类似利用 Eloquent 从数据库获取用户信息。
注入 UserRepository 后,我们可以在其根本上封装其他实现,也可以仿照或者创建一个假的 UserRepository 实现用于测试。

phplaravel容器技巧_ Laravel 56 文档  底层事理  做事容器

深入理解 Laravel 做事容器对付构建功能强大的大型 Laravel 运用而言至关主要,对付贡献代码到 Laravel 核心也很有帮助。

phplaravel容器技巧_ Laravel 56 文档  底层事理  做事容器
(图片来自网络侵删)
绑定

绑定根本

险些所有的做事容器绑定都是在做事供应者中完成。
因此本文档的演示例子用到的容器都是在做事供应者中绑定。

注:如果一个类没有基于任何接口那么就没有必要将其绑定到容器。
容器并不须要被奉告如何构建工具,由于它会利用 PHP 的反射做事自动解析出详细的工具。

大略的绑定

在一个做事供应者中,可以通过 $this->app 变量访问容器,然后利用bind 方法注册一个绑定,该方法须要两个参数,第一个参数是我们想要注册的类名或接口名称,第二个参数是返回类的实例的闭包:

$this->app->bind('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient'));});

把稳到我们将容器本身作为解析器的一个参数,然后我们可以利用该容器来解析我们正在构建的工具的子依赖。

绑定一个单例

singleton 方法绑定一个只会解析一次的类或接口到容器,然后接下来对容器的调用将会返回同一个工具实例:

$this->app->singleton('HelpSpot\API', function ($app) { return new HelpSpot\API($app->make('HttpClient'));});

绑定实例

你还可以利用 instance 方法绑定一个已存在的工具实例到容器,随后调用容器将总是返回给定的实例:

$api = new HelpSpot\API(new HttpClient);$this->app->instance('HelpSpot\Api', $api);

绑定原始值

你可能有一个吸收注入类的类,同时须要注入一个原生的数值比如整型,可以结合高下文轻松注入这个类须要的任何值:

$this->app->when('App\Http\Controllers\UserController') ->needs('$variableName') ->give($value);

绑定接口到实现做事容器的一个非常强大的功能是其绑定接口到实现。
我们假设有一个 EventPusher 接口及实在现类 RedisEventPusher ,编写完该接口的 RedisEventPusher 实现后,就可以将其注册到做事容器:

$this->app->bind( 'App\Contracts\EventPusher', 'App\Services\RedisEventPusher');

这段代码见告容器当一个类须要 EventPusher 的实现时将会注入 RedisEventPusher,现在我们可以在布局器或者任何其它通过做事容器注入依赖的地方进行 EventPusher 接口的依赖注入:

use App\Contracts\EventPusher;/ 创建一个新的类实例 @param EventPusher $pusher @return void/public function __construct(EventPusher $pusher){ $this->pusher = $pusher;}

高下文绑定

有时侯我们可能有两个类利用同一个接口,但我们希望在每个类中注入不同实现,例如,两个掌握器依赖 Illuminate\Contracts\Filesystem\Filesystem 左券的不同实现。
Laravel 为此定义了大略、平滑的接口:

use Illuminate\Support\Facades\Storage;use App\Http\Controllers\VideoController;use App\Http\Controllers\PhotoControllers;use Illuminate\Contracts\Filesystem\Filesystem;$this->app->when(PhotoController::class) ->needs(Filesystem::class) ->give(function () { return Storage::disk('local'); });$this->app->when(VideoController::class) ->needs(Filesystem::class) ->give(function () { return Storage::disk('s3'); });

标签

少数情形下,我们须要解析特定分类下的所有绑定,例如,你正在构建一个吸收多个不同 Report 接口实现的报告聚合器,在注册完 Report 实现之后,可以通过 tag 方法给它们分配一个标签:

$this->app->bind('SpeedReport', function () { //});$this->app->bind('MemoryReport', function () { //});$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');

这些做事被打上标签后,可以通过 tagged 方法来轻松解析它们:

$this->app->bind('ReportAggregator', function ($app) { return new ReportAggregator($app->tagged('reports'));});

扩展绑定

extend 方法许可对解析做事进行修正。
例如,当做事被解析后,可以运行额外代码装饰或配置该做事。
extend 方法吸收一个闭包来返回修正后的做事:

$this->app->extend(Service::class, function($service) { return new DecoratedService($service);});解析

make 方法

有很多办法可以从容器中解析工具,首先,你可以利用 make 方法,该方法吸收你想要解析的类名或接口名作为参数:

$fooBar = $this->app->make('HelpSpot\API');

如果你所在的代码位置访问不了 $app 变量,可以利用赞助函数resolve:

$api = resolve('HelpSpot\API');

某些类的依赖不能通过容器来解析,你可以通过关联数组办法将其通报通报到 makeWith 方法来注入:

$api = $this->app->makeWith('HelpSpot\API', ['id' => 1]);

自动注入

末了,也是最常用的,你可以大略的通过在类的布局函数中对依赖进行类型提示来从容器中解析工具,掌握器、事宜监听器、行列步队任务、中间件等都是通过这种办法。
在详细实践中,这是大多数工具从容器中解析的办法。

容器会自动为其解析类注入依赖,例如,你可以在掌握器的布局函数中为运用定义的仓库进行类型提示,该仓库会自动解析并注入该类:

<?phpnamespace App\Http\Controllers;use App\Users\Repository as UserRepository;class UserController extends Controller{ / 用户仓库实例 / protected $users; / 创建一个掌握器实例 @param UserRepository $users @return void / public function __construct(UserRepository $users) { $this->users = $users; } / 通过指定ID显示用户 @param int $id @return Response / public function show($id) { // }}容器事宜

做事容器在每一次解析工具时都会触发一个事宜,可以利用 resolving 方法监听该事宜:

$this->app->resolving(function ($object, $app) { // Called when container resolves object of any type...});$this->app->resolving(HelpSpot\API::class, function ($api, $app) { // Called when container resolves objects of type \"大众HelpSpot\API\"大众...});

正如你所看到的,被解析的工具将会通报给回调函数,从而许可你在工具被通报给消费者之前为其设置额外属性。

PSR-11

Laravel 的做事容器实现了 PSR-11 接口。
以是,你可以通过类型提示 PSR-11 容器接口来获取 Laravel 容器的实例:

use Psr\Container\ContainerInterface;Route::get('/', function (ContainerInterface $container) { $service = $container->get('Service'); //});

注:如果绑定到容器的唯一标识有冲突调用 get 方法会抛出非常。

注:强烈推举阅读深入理解掌握反转(IoC)和依赖注入(DI)深入理解做事容器和做事供应者的实现事理。

标签:

相关文章

phpcomposermac技巧_mac安装composer

1. 创建一个存放composer命令的目录打开Terminal,在家目录创建一个bin目录(有就不用创建了 :sudo mkdi...

网站建设 2024-12-12 阅读0 评论0