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

Pimple-一个简单的PHP依赖注入容器

时间:2023-03-30 03:37:48 PHP

链接官方网站WebSiteGitHub-Pimple这是Pimple3.x的文档。如果您使用的是Pimple1.x,请查看Pimple1.x文档。阅读Pimple1.x代码也是了解更多有关如何创建简单依赖注入容器的好方法,较新版本的Pimple更注重性能。Pimple-用于PHP安装的简单依赖注入容器在您的项目中使用Pimple之前,将其添加到您的composer.json文件中:$./composer.pharrequirepimple/pimple~3.0或者,Pimple也可作为PHPC扩展使用:$gitclonehttps://github.com/silexphp/Pimple$cdPimple/ext/pimple$phpize$./configure$make$makeinstalluse创建容器实例usePimple\Container;$容器=新容器();与许多其他依赖注入容器一样,Pimple管理两种不同类型的数据:服务和参数定义服务服务是一个对象,可以成为更大系统的一部分,服务的一些示例:数据库连接、模板引擎、邮件服务。几乎任何全局对象都可以是服务。服务通过匿名函数定义,返回一个对象的实例//定义一些服务$container['session_storage']=function($c){returnnewSessionStorage('SESSION_ID');};$container['session']=function($c){returnnewSession($c['session_storage']);};请注意,匿名函数可以访问当前容器实例,从而允许引用其他服务或参数。由于对象仅在获取时创建,因此定义的顺序无关紧要。使用定义的服务也很简单://获取会话对象$session=$container['session'];//上面的调用大致相当于下面的代码://$storage=newSessionStorage('SESSION_ID');//$session=newSession($storage);定义工厂服务默认情况下,每次获取服务时,Pimple都会返回相同的实例。如果您想为所有调用返回不同的实例,请使用factory()方法包装您的匿名函数。$container['session']=$container->factory(function($c){returnnewSession($c['session_storage']);});现在,每次调用$container['session']都会返回一个新的会话实例。定义参数定义参数允许从外部简化容器的配置并存储全局值//定义一些参数$container['cookie_name']='SESSION_ID';$container['session_storage_class']='SessionStorage';您现在可以通过覆盖session_storage_class参数而不是重新定义服务定义来轻松更改cookie名称。保护参数由于Pimple将匿名函数视为服务定义,因此需要使用protect()方法将匿名函数包装为参数:$container['random_func']=$container->protect(function(){returnrand();});修改已定义的服务在某些情况下,您可能需要在定义服务定义后对其进行修改。创建服务后,您可以使用extend()方法添加其他代码:$container['session_storage']=function($c){returnnew$c['session_storage_class']($c['cookie_name']);};$container->extend('session_storage',function($storage,$c){$storage->...();return$storage;});第一个参数是要扩展的服务对象的名称,第二个参数是访问对象实例和容器的函数。如果您重复使用同一个库,您可能希望将一个项目的某些服务重用到下一个项目。通过实现Pimple\ServiceProviderInterface接口,将您的服务打包到Provider程序中然后,注册Provider$pimple->register(newFooProvider());在容器上获取??服务创建方法当你访问一个对象时,Pimple会自动调用你定义的匿名函数为你创建服务对象。如果你想获得对这个函数的原始访问,你可以使用raw()方法:$container['session']=function($c){returnnewSession($c['session_storage']);};$sessionFunction=$container->raw('session');PSR-11兼容性由于历史原因,Container类没有实现PSR-11ContainerInterface。但是,Pimple提供了一个辅助类,允许您将代码与Pimple容器类分离。PSR-11容器类Pimple\Psr11\Container类允许您使用Psr\Container\ContainerInterface方法访问Pimple容器的内容:usePimple\Container;usePimple\Psr11\ContainerasPsrContainer;$container=newContainer();$container['service']=function($c){returnnewService();};$psr11=newPsrContainer($container);$controller=function(PsrContainer$container){$service=$container->get('service');};$控制器($psr11);使用PSR-11服务定位有时,一个服务需要访问多个其他服务,但不确定所有这些服务是否会被实际使用。在这些情况下,您可能希望延迟加载这些服务。传统的解决方案是注入整个服务容器以获得真正需要的服务。但是,不推荐这样做,因为它使服务对应用程序其他部分的访问过于广泛,并隐藏了它们的实际依赖关系。ServiceLocator旨在通过访问一组预定义的服务来解决此问题,同时仅在实际需要时实例化它们。它还允许您以与注册时不同的名称提供服务。例如,您可能希望使用一个对象,该对象期望EventDispatcherInterface实例在名称event_dispatcher下可用,并且您的事件调度程序在名称dispatcheruseMonolog\Logger;usePimple\Psr11\ServiceLocator;usePsr\Container\ContainerInterface下注册;useSymfony\Component\EventDispatcher\EventDispatcher;classMyService{/***"logger"必须是Psr\Log\LoggerInterface的实例*"event_dispatcher"必须是Symfony\Component\EventDispatcher\EventDispatcherInterface的实例*/private$服务;公共函数__construct(ContainerInterface$services){$this->services=$services;}}$container['logger']=function($c){returnnewMonolog\Logger();};$container['dispatcher']=function(){returnnewEventDispatcher();};$container['service']=function($c){$locator=newServiceLocator($c,array('logger','event_dispatcher'=>'dispatcher'));返回新的MyService($locator);};延迟引用服务集合在数组中传递服务实例集合可能效率低下,因为使用集合的类只需要稍后调用它的方法来迭代它。如果存储在集合中的服务之一与使用该服务的类之间存在循环依赖性,它也会导致问题。ServiceIterator类可以帮助您解决这些问题。它在实例化期间接收服务名称列表并在迭代时检索服务usePimple\Container;usePimple\ServiceIterator;classAuthorizationService{private$voters;公共函数__construct($voters){$this->voters=$voters;}publicfunctioncanAccess($resource){foreach($this->votersas$voter){if(true===$voter->canAccess($resource){returntrue;}}returnfalse;}}$container=newContainer();$container['voter1']=function($c){returnnewSomeVoter();}$container['voter2']=function($c){returnnewSomeOtherVoter($c['auth']);}$container['auth']=function($c){returnnewAuthorizationService(newServiceIterator($c,array('voter1','voter2')));}谁在支持Pimple?Pimple由Pimple由Symfony框架的创造者FabienPotencier撰写,在MIT许可下发布,原创文章欢迎转载,转载请注明出处,谢谢。原文链接地址:http://dryyun.com/2018/04/17/...作者:dryyun发表日期:2018-04-1714:30:29