Laravel学习教程之IOC容器的介绍与用例
发布时间 - 2026-01-11 02:48:00 点击率:次前言

Laravel使用IoC(Inversion of Control,控制倒转,这是一个设计模式,可以先查看下百科)容器这个强有力的工具管理类依赖。依赖注入(也是一种设计模式,一般用于实现IoC)是一个不用编写固定代码来处理类之间依赖的方法,相反的,这些依赖是在运行时注入的,这样允许处理依赖时具有更大的灵活性。
理解 Laravel IoC容器是构建强大应用程序所必要的,也有助于Laravel 核心本身。下面话不多说了,来一起看看详细的介绍吧。
基本用例
绑定一个类型到容器
IoC 容器有两种方法来解决依赖关系:通过闭包回调或者自动解析。首先,我们来探究一下闭包回调。首先,需要绑定一个“类型”到容器中:
App::bind('foo', function($app)
{
return new FooBar;
});
从容器中取得一个类型
$value = App::make('foo');
当执行 App::make 方法,闭包函数被执行并返回结果。
绑定一个”共享“类型到容器
有时,你只想将绑定到容器的类型处理一次,然后接下来从容器中取得的都应该是相同实例:
App::singleton('foo', function()
{
return new FooBar;
});
绑定一个已经存在的类型实例到容器
你也可以使用instance方法,将一个已经存在的对象接口绑定到容器中:
$foo = new Foo;
App::instance('foo', $foo);
哪里去注册绑定呢
IoC绑定,很像事件句柄或者路由过滤,通常在"bootstrap code(引导代码)"之后完成。换句话说,它们在你的应用程序准备处理请求,也即是在一个路由或者控制器被实际执行之前执行。和其他引导代码一样,start文件通常作为IoC绑定注册一种方法。另外,你可以创建一个app/ioc.php(文件名不一定一样)文件,并在start文件中包含它。
如果你的应用程序有很大量IoC绑定,或者你想根据不同的分类将IoC绑定分割到不同的文件,你可以尝试在服务提供器(见下面)中进行绑定
自动解析
取得一个类
IoC容器足够强大,在许多场景下不需要任何配置就能取得类。例如
class FooBar {
public function __construct(Baz $baz)
{
$this->baz = $baz;
}
}
$fooBar = App::make('FooBar');
注意:我们虽然没有在容器中注册FooBar类,容器仍然可以取得该类,甚至自动注入Baz依赖!
当某个类型没有绑定到容器,IoC容器将使用 PHP 的反射工具来检查类和读取构造器的类型提示。使用这些信息,容器可以自动构建类实例。
绑定一个接口实现
然而,在某些情况下,一个类可能依赖某个接口实现,而不是一个 “具体的类”。当在这种情况下,App::bind方法必须通知容器注入哪个接口实现:
App::bind('UserRepositoryInterface', 'DbUserRepository');
现在考虑下这个控制器:
class UserController extends BaseController {
public function __construct(UserRepositoryInterface $users)
{
$this->users = $users;
}
}
由于我们将 UserRepositoryInterface 绑定了具体类,DbUserRepository 在该控制器创建时将会被自动注入到该控制器。
实际用例
Laravel 提供了几个方法使用 IoC 容器增强应用程序可扩展性和可测试性。一个主要的例子是取得控制器。所有控制器都通过 IoC 容器取得,意味着可以在控制器构造方法中对依赖的类型提示,它们将自动被注入。
对控制器的依赖关系做类型提示
class OrderController extends BaseController {
public function __construct(OrderRepository $orders)
{
$this->orders = $orders;
}
public function getIndex()
{
$all = $this->orders->all();
return View::make('orders', compact('all'));
}
}
在这个例子中,OrderRepository 将会自动注入到控制器。意味着当 单元测试 模拟请求时,OrderRepository 将会绑定到容器以及注入到控制器中,允许无痛与数据库层交互。
IoC 使用的其他例子
过滤器, composers, 和 事件句柄也能够从IoC容器中获取到。当注册它们的时候,只需要把它们使用的类名简单给出即可:
Route::filter('foo', 'FooFilter');
View::composer('foo', 'FooComposer');
Event::listen('foo', 'FooHandler');
服务提供器
服务器提供器是将一组相关 IoC 注册到单一路径的有效方法。将它们看做是一种引导组件的方法。在服务器提供器里,你可以注册自定义的验证驱动器,使用 IoC 容器注册应用程序仓库类,甚至是自定义 Artisan 命令。
事实上,大多数核心 Laravel 组件包含服务提供器。应用程序所有注册在服务提供器的均列在 app/config/app.php 配置文件的 providers 数组中。
定义服务提供器
要创建服务提供器,只需继承 Illuminate\Support\ServiceProvider 类并且定义一个 register 方法:
use Illuminate\Support\ServiceProvider;
class FooServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('foo', function()
{
return new Foo;
});
}
}
注意:在 register 方法,应用程序通过 $this->app 属性访问 IoC 容器。一旦你已经创建了提供器并且想将它注册到应用程序中, 只需简单的放入 app 配置文件里 providers 数组中。
运行时注册服务提供器
你也可以使用 App::register 方法在运行时注册服务提供器:
App::register('FooServiceProvider');
容器事件
注册获取事件监听者
容器在每次获取对象时都触发一个事件。你可以通过使用 resolving 方法来监听该事件:
App::resolvingAny(function($object)
{
//
});
App::resolving('foo', function($foo)
{
//
});
注意:获取到的对象将会传入回调函数中。
译者:mpandar(马胜盼)
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# laravel
# ioc容器
# laravel的ioc容器
# ioc
# Laravel 5.4向IoC容器中添加自定义类的方法示例
# 绑定
# 应用程序
# 你可以
# 将会
# 只需
# 是一个
# 是在
# 回调
# 句柄
# 你也
# 器中
# 自定义
# 可以使用
# 方法来
# 配置文件
# 想将
# 组中
# 几个
# 是一种
# 在这个
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
Linux系统命令中tree命令详解
网站图片在线制作软件,怎么在图片上做链接?
Laravel如何实现API版本控制_Laravel API版本化路由设计策略
Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】
Python高阶函数应用_函数作为参数说明【指导】
Laravel Fortify是什么,和Jetstream有什么关系
免费视频制作网站,更新又快又好的免费电影网站?
如何快速生成ASP一键建站模板并优化安全性?
成都网站制作公司哪家好,四川省职工服务网是做什么用?
Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何在IIS7上新建站点并设置安全权限?
Laravel怎么调用外部API_Laravel Http Client客户端使用
如何在阿里云完成域名注册与建站?
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
如何在建站之星绑定自定义域名?
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
Laravel Debugbar怎么安装_Laravel调试工具栏配置指南
七夕网站制作视频,七夕大促活动怎么报名?
Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门
为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
Swift开发中switch语句值绑定模式
Laravel安装步骤详细教程_Laravel环境搭建指南
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
如何获取免费开源的自助建站系统源码?
如何选择PHP开源工具快速搭建网站?
网站制作报价单模板图片,小松挖机官方网站报价?
Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询
香港服务器网站卡顿?如何解决网络延迟与负载问题?
详解Android——蓝牙技术 带你实现终端间数据传输
JavaScript数据类型有哪些_如何准确判断一个变量的类型
Python企业级消息系统教程_KafkaRabbitMQ高并发应用
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
如何破解联通资金短缺导致的基站建设难题?
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
微信小程序 配置文件详细介绍
如何用好域名打造高点击率的自主建站?
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
如何在Windows虚拟主机上快速搭建网站?
高防服务器租用指南:配置选择与快速部署攻略
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
利用JavaScript实现拖拽改变元素大小

