当前位置: 首页 > 后端技术 > PHP

使用Laravel服务容器的优势

时间:2023-03-30 05:27:31 PHP

本文转载自我的个人博客原地址SampsonBlog如果说laravel框架的核心,那无疑是服务容器。了解服务容器的概念对于我们使用laravel来说是非常重要的。应该说了解服务容器的概念是区分是否上手laravel的重要条件。因为整个框架是建立在服务容器的基础上的。Laravel服务容器就像一个高度自动化的工厂。您需要自定义模型并使用特定的界面来制造它。由于使用了服务容器,laravel中的大多数对象都是这样实例化的:$obj1=$container->make('class1','class2');$obj2=$container->make('class3','class4');但是在不使用服务容器的情况下,也可以通过下面的方法来完成::$obj1=newclass1(newclass2());$obj2=newclass3(newclass4());那么使用服务容器到底有什么优势呢?下面通过一些具体的例子来分析一下它的优点:例1.发送邮件我们将发送邮件的功能封装到一个类中,在需要使用的时候实例化并调用发送方法。以下是不使用laravel服务容器的常用方式:/***发送邮件服务类*/classEmailService{publicfunctionsend(){//todo发送邮件方法}}//如果你想在任何地方发送邮件,我们将复制下面这两行代码$emailService=newEmailService();$emailService->发送();使用laravel服务容器后:$this->app->bind('emailService',function($app){returnnewEmailService();});//如果我们想在任何地方发送邮件,可以复制以下内容两行代码$emailService=app('emailService');$emailService->send();这使得我们的代码更加简洁,并且因为有了中间层,提高了灵活性(解耦),所以无论是测试(我们可以在测试时伪造类来替换EmailService类)还是优化EmailService类,都变成了更方便。//只需要改这一个地方$this->app->bind('emailService',function($app){returnnewSupperEmailService();});我们根本不需要去触及调用的其他部分,如果我们没有这个绑定的话,如果不指定操作,就得在每个使用邮件服务的地方都做改动。//凡是用到EamilSerice类的地方都要改。$emailService=newSupperEmailService();$emailService->send();例子2.实现单例模式还是上面的例子。出于性能考虑,需要SupperEamilService类实现单例模式,所以在不使用laravel服务容器的情况下,将SupperEmailService类改成如下:classSupperEamilService{//创建一个静态私有变量来保存该类的对象staticprivate$实例;//防止直接创建对象privatefunction__construct(){}//防止克隆对象privatefunction__clone(){}staticpublicfunctiongetInstance(){//判断$instance是否为Uni对象//如果不是,则创建如果(!self::$instanceinstanceofself){self::$instance=newself();}返回自我::$实例;}//发送邮件方法publicfunctionsend(){}}另外,由于现在SupperEamilService类的构造函数是private的,不能通过new关键字实例化对象,所以每个实例化SupperEmailService类的地方都要改成这样:$emailService=SupperEmailService::getInstance();$emailService->send();laravel服务容器天然支持单例,下面是laravel的实现://把bind改为单例即可$this->app->singleton('emailService',function($app){returnnewSupperEmailService();});实现单例只需要改一行代码,把原来的bind方法改成单例,通过容器把单例取出来,真是太方便了。示例3.旅行者去旅行。这个例子假设一个旅行者去西藏旅游,他可以坐火车(train)也可以步行(leg)。不要使用laravel服务容器:}}类Leg实现TrafficTool{publicfunctiongo(){echo"leg..";}}classTraveler{/***@varLeg|null|火车*旅行工具*/protected$_trafficTool;公共函数__construct(TrafficTool$trafficTool){$this->_trafficTool=$trafficTool;}publicfunctionvisitTibet(){$this->_trafficTool->go();}}当旅行者想坐火车旅行时,我们通常这样写:visitTibet();其实这种写法很好,因为对出行工具的依赖已经通过接口转移到外部了。但是在使用new实例化对象的时候,还是会存在依赖关系。比如上面的$tra=newTraveler($trafficTool),也就是说我们在创建Traveler之前必须要有一个$trafficTool,也就是Traveler依赖于trafficTool。当使用new实例化Traveler时,Traveler和trafficTool之间存在耦合。这样,两个组件就无法分开。下面我们来看看laravel服务容器是如何实现的:绑定服务容器中的类//在服务容器中绑定类$this->app->bind('TrafficTool','Train');$this->app->bind('旅行者','旅行者');}}实例化对象make('Traveller');$tra->visitTibet();当我们使用服务容器获取旅游类的对象时,容器会自动注入该对象需要的参数。在此之前,我只需要绑定一个具体的类,体现了真正的自动化,将出行类和出行工具类完全解耦。当我们需要改变行进方式时,只需要改变绑定即可。综上所述,上面给出了几个简单的例子。如果你能够充分理解和掌握laravel服务容器,将会为你在实际开发中提供更多便利。当然,它并不完美,下一篇博客将描述它的不足之处。总之,关键是在实际使用中扬长避短。