一个php请求一个进程,请求结束了就全部释放了。那用容器和直接new那个类有什么区别?
跟 PHP 无关,这是面向对象语言所共同的编程范式。
所有语言中 DI/IoC 的好处都是一样的。
如果你的 PHP 代码完全是类似 C 的那种面向过程的写法,根本没用到 OOP,那确实用不着容器。
1 回答4.2k 阅读✓ 已解决
3 回答1.9k 阅读✓ 已解决
2 回答2.3k 阅读✓ 已解决
2 回答853 阅读✓ 已解决
1 回答1.4k 阅读✓ 已解决
2 回答2.3k 阅读
1 回答717 阅读✓ 已解决
容器并不限定于某个语言,而是一种编程思想。
对于 PHP FPM 的运行机制而言,这种容器(IoC, 依赖注入容器)确实没有发挥像常驻型应用那样明显。
但是对于项目来说,这还是有一定作用的。大部分时候,容器更多的在于对象的管理,拓展到依赖注入后,利用依赖注入容器,就更加的如虎添翼了。
比如在 Laravel 中,容器可以
绑定实现
、绑定单例
,当然还有最重要的创建对象
。相对于使用 new 而言,使用容器创建对象时,你对要创建的对象目标及其依赖是可控的。比如举个比较极端的例子,你要
new DB()
来创建一个对象,现在你在项目各处需要使用 DB 的地方都写了这个new DB()
的代码,假设有一天,你要替换这 DB ,你要做的就是去替换所有new DB()
的地方,当然,这个简单的问题还有替代方案,比如使用 class_alias。如果你使用容器来管理、创建获取这个 DB 对象,
app(DB::class)
现在,你就可以拿到 DB 的示例,现在看起来, 这样的写法比 new DB 还多几个字符呢。但是如果现在你要替换掉 DB ,那就可以在替换容器中的绑定。就像这样。app()->bind(DB::class, Redis::class)
,现在,优势就体现出来的,你现在使用app(DB::class)
创建实例的地方,现在都将会变成 Redis ,你不用再去修改更多的代码,你甚至可以动态的移除这个绑定,让他随时获得原来的对象。且更加利于单测中的对象替换。
当然前述的变化一般都很少出现,考虑一下更容易出现的情况,现在有一个 OSS 的 SDK ,用来管理 OSS 上面的资源,你每次操作的时候,都需要
new OSS($endpoint, $user, $key)
,以完成对 OSS 的认证,进而进行操作。如果每次都这样 new 一个对象,就会很麻烦,你肯定想到了,我可以创建一个全局函数,或者一个 Helper 静态方法Helper::getOss()
在这个方法里面 new 就好了,甚至还可以用静态变量实现单例,一个 OSS 如此,后面来一个 Redis、再来个 ElasticSearch 等等更多,你就需要创建更多的 Helper 方法,逐渐的就会不便于管理。但是如果你使用容器,你就可以简单在容器进行绑定
app()->instance(OSS::class, new OSS($endpoint, $user, $key));
,后续使用的时候直接app(OSS::class)
等等就可以创建并一个实例。这就是最基本的容器使用,他看起来有点儿像工厂。
在现代化框架中,使用反射对容器的还添加了自动依赖处理等。
原回答 ↓
划掉容器化更大的意义是在标准化部署。容器内本身是一个操作系统,这和 PHP 的一个请求一个进程并没有什么关系。使用同一镜像启动的的容器,可以让你在不同平台(有一定前提)上都拥有同样的运行环境,从而解决因环境不一样导致的一些奇怪的问题。