# 依赖注入 1。依赖:A做一件事时,必须要B帮忙,A依赖B。 比如手机充电, 需要找一个带电的插座吧。 没有带电插座就不行。 ![](https://img.kancloud.cn/e8/8b/e88bc775706931eb4e4cbc1d9c597cec_500x500.png) - - - - - - 2。当然我们用充电保也可以啊。那来看看程序吧。一个收货地址解释服务的事 ``` <pre class="calibre7">``` <?php //A 平台 收货地址解释类 class AAddressApi { public function explain($address) { return ['xxx省xx市', 'X三', 'xx手机号码']; } } //程序有一个接口,代理复制客户的 商品信息跟收货地址,复制粘贴就可以,下单 class PlaceOrder { //分析字符串中的 商品信息,跟地址信息 public function explain($str) { //把字符串中的,商品信息,跟收货地址信息分离出来 [$product, $address] = $this->product2address($str); //依赖 AAddressApi 这个类,这里写死了 AAddressApi,我必须要它,没有它我就不行 [$addr, $name, $phone] = (new AAddressApi())->explain($address); var_dump("{$product}下单成功,发货到{$addr},{$name},{$phone}"); } public function product2address($str) { return ['华为手机Mate 80PRO', 'XXX省xx市x三,xx手机号码']; } } $placeOrder = new PlaceOrder(); $placeOrder->explain('xxx'); ``` 3。然后有一天 AAddressApi 这个平台,老板转做包租公了,平台就没做了。 那个类 PlaceOrder 就会出错了。那怎么让 就算 A平台关闭了,PlaceOrder 也不出错呢 。就是不要把 依赖写死。 ``` //A 平台收货地址解释类 class AAddressApi { public function explain($address) { return ['xxx省xx市', 'X三', 'xx手机号码']; } } //百度平台 收货地址解释类 class BaiduAddressApi { public function explain($address) { return ['xxx省xx市', 'X三', 'xx手机号码']; } } class PlaceOrder { public $addressApi; //依赖的类,从外面,传递进来 public function __construct($addressApi) { $this->addressApi = $addressApi; } //分析字符串中的 商品信息,跟地址信息 public function explain($str) { [$product, $address] = $this->product2address($str); //不知道使用的是哪个对象。只要能解释地址就行 [$addr, $name, $phone] = $this->addressApi->explain($address); var_dump("{$product}下单成功,发货到{$addr},{$name},{$phone}"); } public function product2address($str) { return ['华为手机Mate 80PRO', 'XXX省xx市x三,xx手机号码']; } } //依赖的类,new 的时候,通过参数,传递进去 $placeOrder = new PlaceOrder(new AAddressApi()); $placeOrder->explain('xxx'); $placeOrder = new PlaceOrder(new BaiduAddressApi()); $placeOrder->explain('xxx'); ``` 4。这样 PlaceOrder 不需要修改就,也可以正常运行了。那问题来了,为什么要这样写呢把 ``` //类如,下面这种写法 new PlaceOrder(new AAddressApi()) //A平台没用了,所有地方,不都得要修改。 new PlaceOrder(new BaiduAddressApi()) ``` 5。而且每次 new PlaceOrder() 还得写成 new PlaceOrder(new BaiduAddressApi()),更加麻烦。 下面以TP6框架为例,在”简单工厂“中介绍相关内容