博主信息
張浩剛
博文
42
粉絲
4
評論
0
訪問量
5079
積分:0
P豆:97

新疆十一选五吧:mvc 服務容器,控制反轉

2019年12月11日 10:29:52閱讀數:617博客 / 張浩剛 / php

根目錄下文件

Controller.php

 新疆十一选五预测号码今天 www.envkt.com 
  1. <?php
  2. //本頁面 是服務容器的控制反轉,將接口下的類,控制器的類反轉到容器中控制
  3. //根目錄use調用,第一個一定是 \文件夾名\..\php的文件名
  4. use \view\iVehicle;
  5. use \view\Car;
  6. use \view\Bus;
  7. require __DIR__ . '/Autoload.php';
  8. //容器類
  9. class Container
  10. {
  11. // 閉包數組
  12. private static $binds = [];
  13. // 實例數組
  14. private static $instance = [];
  15. // 將閉包或實例綁定到對應的容器中
  16. public function bind($abstract,$concrete)
  17. {
  18. // 將類實例化的閉包綁定到閉包數組中
  19. // 按照約定,閉包是用來創建對象的
  20. // 重要編碼約定: 它的構造方法第一個參數必須是 "容器對象", 便于統一管理 "對象依賴關系"
  21. // 如果第二個參數是閉包類型, 說明該類實例并未創建,應該將實例化過程/閉包綁定到容器中
  22. if($concrete instanceof Closure){
  23. static::$binds[$abstract] = $concrete;
  24. }else{
  25. // 否則,表示該類已被實例化,直接將 "類實例" 綁定到實例數組中即可
  26. static::$instance[$abstract] = $concrete;
  27. }
  28. }
  29. // 從容器中取出指定實例, $parameters是實例的依賴對象(數組形式提供)
  30. public function make($abstract,$parameters = [])
  31. {
  32. // 如果容器中已有指定類實例,則直接返回
  33. if(isset(static::$instance[$abstract])){
  34. return static::$instance[$abstract];
  35. }else{
  36. // 如果沒有, 則執行閉包容器中的閉包方法,完成實例化工作,并返回該實例
  37. // 因為所有依賴都使用容器統一管理,所以需要將容器對象注入到所有依賴對象的參數列表中
  38. // 默認容器必須是依賴對象參數列表中的第一個參數,使用array_unshift()就可以
  39. // 注意, $this 是第一個參數, 即當前容器對象,這里就是本服務容器Container
  40. array_unshift($parameters, $this);
  41. // 執行閉包, 如果閉包生成的對象依賴于其它對象,可通過$parameters設置
  42. return call_user_func_array(static::$binds[$abstract],$parameters);
  43. }
  44. }
  45. }
  46. //控制器
  47. class Controller
  48. {
  49. // 交通工具
  50. private static $Traffic;
  51. // 構造方法:接口 接入,第二個$traff就是接口下的對象類:Car,Bus 是數組,通過外部服務容器傳參
  52. public function __construct(iVehicle $traff)
  53. {
  54. static::$Traffic = $traff;
  55. }
  56. public function travelMode()
  57. {
  58. return static::$Traffic->drive();
  59. }
  60. }
  61. //容器對象
  62. $container = new Container();
  63. //將汽車類綁定到閉包數組中
  64. //將$container做為閉包參數, 主要用來管理依賴對象的,本例中除調用類外,其它類并未使用到依賴對象
  65. $container->bind('car', function(Container $container){return new Car();});
  66. $container->bind('bus', function(Container $container){return new Bus();});
  67. // 同時將調用類:控制器類也綁定到容器中
  68. // Controller構造方法需要一個實現了iVehicle接口的對象,而該對象需要使用容器中的make()方法獲取
  69. // 根據make($container, $parameters)方法簽名, 該閉包簽名的第一個參數是容器對象,第二個參數是依賴的對象
  70. // 注意, 為了簡化, 約定將依賴對象,通過構造方式注入到當前對象中
  71. $container->bind('controller', function(Container $container, $traffi){
  72. return new Controller($container->make($traffi));
  73. });
  74. //客戶端
  75. //從容器中取出已實例化的容器類對象 (此時依賴對象已經通過構造方法注入到了控制器類中了)
  76. $controller = $container->make('controller',['car']);
  77. echo $controller->travelMode();//汽車
  78. $controller = $container->make('controller',['car']);
  79. echo $controller->travelMode();//公交車
  80. //如果只想從容器中取出接口下的某一個對象類
  81. $car = $container->make('car');
  82. echo $car->drive();
  83. // 為了便于后面調用, 我們將這四個對象打包到一個數組中管理
  84. $vehicles = compact('car', 'train', 'plane', 'ship');
  85. // 如果已經獲取到了依賴對象, 那么就不必使用make()來調用Travel4對象了,直接實例化它就行
  86. foreach ($vehicles as $vehicle) {
  87. $travel = new Controller($vehicle);
  88. echo $travel->travelMode(), '<br>';
  89. }
  90. // 到現在為止, 我們已經實現了依賴注入也控制反轉
  91. // 基本流程是:
  92. // 1. 依賴注入: 如果一對象需要依賴另一個對象才能完成某項操作,則必須通過方法參數的形式將依賴對象注入當前到對象中
  93. // 2. 控制反轉: 依賴對象的實例化與該對象自身的依賴關系處理, 由一個叫服務容器的類統一處理,實現了對象控制權的轉移

Autoload.php

  1. <?php
  2. spl_autoload_register(function (string $class) {
  3. $file = str_replace('\\', '/', $class) . '.php';
  4. if (!is_file($file)) {
  5. throw new \Exception("file don't exists");
  6. }
  7. require $file;
  8. });

根 \view文件夾

iVehicle.php 接口文件

  1. <?php
  2. namespace view;
  3. interface iVehicle
  4. {
  5. public function drive();
  6. }

Car.php

  1. <?php
  2. namespace view;
  3. class Car implements iVehicle
  4. {
  5. public function drive()
  6. {
  7. return '小汽車';
  8. }
  9. }

Bus.php

  1. <?php
  2. namespace view;
  3. class Bus implements iVehicle
  4. {
  5. public function drive()
  6. {
  7. return '公交車';
  8. }
  9. }

全部評論

文明上網理性發言,請遵守新聞評論服務協議

條評論
暫無評論暫無評論!