博客列表 >12月04日_PHP类中静态成员和MVC(依赖注入、服务容器和Facade门面)

12月04日_PHP类中静态成员和MVC(依赖注入、服务容器和Facade门面)

fkkf467
fkkf467原创
2019年12月06日 14:08:46922浏览

一、类中静态成员

1. 声明静态成员

  1. <?php
  2. // 定义命名空间
  3. namespace _1204;
  4. // 为全局空间中的PDO类导入空间别名
  5. use PDO;
  6. // 1. 创建类
  7. class Db1
  8. {
  9. // 2. 添加类成员
  10. // 添加静态属性
  11. protected static $pdo;
  12. protected static $dsn = 'mysql:host=localhost;dbname=test';
  13. protected static $username = 'root';
  14. protected static $password = 'root';
  15. // 添加静态方法
  16. public static function connect()
  17. {
  18. // 在类中访问当前类的静态成员用 self::
  19. self::$pdo = new PDO(self::$dsn, self::$username, self::$password);
  20. }
  21. // 测试方法
  22. public static function select()
  23. {
  24. // 数据库连接
  25. self::connect();
  26. // 将查询结果以关联数组形式返回
  27. return self::$pdo->query('SELECT * FROM `computer`', PDO::FETCH_ASSOC);
  28. }
  29. }
  30. // 3. 访问类成员
  31. // 在类的外部,访问类中的静态成员,直接用类名进行访问
  32. $result = Db1::select();
  33. foreach ($result as $row) {
  34. echo '<pre>' . print_r($row, true) . '</pre>';
  35. }
  36. ?>

2. 后期静态绑定

  1. <?php
  2. // 定义命名空间
  3. namespace _1204;
  4. // 后期静态绑定使用场景:静态继承的上下文环境中
  5. // 后期静态绑定就是在类成员被调用的时候再动态的绑定,也叫:延迟绑定
  6. use PDO;
  7. // 1. 创建类
  8. class Db2
  9. {
  10. // 2. 添加类成员
  11. // 静态属性
  12. protected static $pdo;
  13. protected static $dsn = 'mysql:host=localhost;dbname=test';
  14. protected static $username = 'root';
  15. protected static $password = 'root';
  16. // 静态方法
  17. public static function connect()
  18. {
  19. // 后期静态绑定就是将需要绑定的静态成员的访问由 self:: ,改为 static::
  20. static::$pdo = new PDO(static::$dsn, static::$username, static::$password);
  21. }
  22. public static function select()
  23. {
  24. // 数据库连接
  25. static::connect();
  26. // 将查询结果以关联数组形式返回
  27. return self::$pdo->query('SELECT * FROM `computer`', PDO::FETCH_ASSOC);
  28. }
  29. }
  30. class Sub extends Db2
  31. {
  32. protected static $username = 'root';
  33. protected static $password = 'root';
  34. // 重写父类中的connect()方法
  35. public static function connect()
  36. {
  37. self::$pdo = new PDO(self::$dsn, self::$username, self::$password);
  38. }
  39. }
  40. // 3. 访问类成员
  41. // 在类的外部,访问类中的静态成员, 直接用类名
  42. // 由于在父类中的select()方法中调用connect()方法时使用了后期静态绑定,
  43. //又由于子类对connect()方法进行了重写,所以这时,用的就是子类中的 connect() 方法
  44. $result = Sub::select();
  45. foreach ($result as $row) {
  46. echo '<pre>' . print_r($row, true) . '</pre>';
  47. }
  48. ?>

二、MVC

1. 模型类 Model.php

  1. <?php
  2. namespace mvc;
  3. // 模型类:用于数据表的操作
  4. class Model
  5. {
  6. public function getData()
  7. {
  8. // 用二维数组来模拟从表中获取到的商品数据
  9. return [
  10. [
  11. 'id' => 1,
  12. 'name' => '苹果电脑',
  13. 'model' => 'MacBook Pro',
  14. 'price' => 25800
  15. ],
  16. [
  17. 'id' => 2,
  18. 'name' => '华为手机',
  19. 'model' => 'P30 Pro',
  20. 'price' => 4988
  21. ],
  22. [
  23. 'id' => 3,
  24. 'name' => '小爱同学',
  25. 'model' => 'AI音箱',
  26. 'price' => 299
  27. ]
  28. ];
  29. }
  30. }

2. 视图类 View.php

  1. <?php
  2. namespace mvc;
  3. // 视图类:渲染数据
  4. class View
  5. {
  6. public function fetch($data)
  7. {
  8. $table = '<table>';
  9. $table .= '<caption>商品信息表</caption>';
  10. $table .= '<tr><th>ID</th><th>品名</th><th>型号</th><th>价格</th></tr>';
  11. foreach ($data as $product) {
  12. $table .= '<tr>';
  13. $table .= '<td>' . $product['id'] . '</td>';
  14. $table .= '<td>' . $product['name'] . '</td>';
  15. $table .= '<td>' . $product['model'] . '</td>';
  16. $table .= '<td>' . $product['price'] . '</td>';
  17. $table .= '</tr>';
  18. }
  19. $table .= '</table>';
  20. return $table;
  21. }
  22. }
  23. echo '<style>
  24. table {border-collapse: collapse; border: 1px solid; width: 500px;height: 150px}
  25. caption {font-size: 1.2rem; margin-bottom: 10px;}
  26. tr:first-of-type { background-color:lightblue;}
  27. td,th {border: 1px solid}
  28. td:first-of-type {text-align: center}
  29. </style>';

3. MVC简单实现

  1. <?php
  2. namespace mvc;
  3. // 1. 加载模型
  4. require 'Model.php';
  5. // 2. 加载视图
  6. require 'View.php';
  7. // 3. 创建控制器
  8. // 控制器:将商品信息表展示出来
  9. class Controller1
  10. {
  11. public function index()
  12. {
  13. // 3.1 获取数据
  14. $model = new Model();
  15. $data = $model->getData();
  16. // 3.2 渲染模板
  17. $view = new View();
  18. return $view->fetch($data);
  19. }
  20. }
  21. // 4. 通过客户端来访问类成员
  22. $controller = new Controller1();
  23. echo $controller->index();
  24. ?>

4. 通过依赖注入,降低耦合度

a. 将注入点改到控制器的普通方法中

  1. <?php
  2. // 依赖注入
  3. // 将类中对其它类的实例化,分离出来, 降低耦合度
  4. //例如:下面将模型/视图类的实例化分离出来
  5. namespace mvc;
  6. // 1. 加载模型
  7. require 'Model.php';
  8. // 2. 加载视图
  9. require 'View.php';
  10. // 3. 创建控制器
  11. class Controller2
  12. {
  13. public function index(Model $model, View $view)
  14. {
  15. // 获取数据
  16. $data = $model->getData();
  17. // 渲染模板
  18. return $view->fetch($data);
  19. }
  20. }
  21. // 4.客户端访问类成员
  22. // 将模型与视图的实例化从控制器分离出来,放到客户端
  23. $model = new Model();
  24. $view = new View();
  25. // 将模型对象与视图对象,以参数的形式再次注入到控制器的方法中
  26. $controller = new Controller2();
  27. echo $controller->index($model, $view);

b. 将注入点改到控制器的构造方法中

  1. <?php
  2. // 依赖注入:将注入点改到控制器的构造方法中
  3. namespace mvc;
  4. // 1. 加载模型
  5. require 'Model.php';
  6. // 2. 加载视图
  7. require 'View.php';
  8. // 3. 创建控制器
  9. class Controller3
  10. {
  11. protected $model;
  12. protected $view;
  13. // 将注入点改到构造方法中,实现了模型与视图对象的共享
  14. public function __construct(Model $model, View $view)
  15. {
  16. $this->model = $model;
  17. $this->view = $view;
  18. }
  19. public function index()
  20. {
  21. // 获取数据
  22. $data = $this->model->getData();
  23. // 渲染模板
  24. return $this->view->fetch($data);
  25. }
  26. }
  27. // 4. 客户端访问类成员
  28. // 将模型与视图的实例化从控制器分离出来,放到客户端
  29. $model = new Model();
  30. $view = new View();
  31. // 将模型对象和视图对象,以参数的形式注入到控制器的构造方法
  32. $controller = new Controller3($model,$view);
  33. echo $controller->index();
  34. ?>

5. 添加服务容器层

  1. <?php
  2. namespace mvc;
  3. // 1. 加载模型
  4. require 'Model.php';
  5. // 2. 加载视图
  6. require 'View.php';
  7. // 添加服务容器层
  8. class Container
  9. {
  10. // 容器属性,就是一个数组,保存着创建对象的方法
  11. protected $instance = [];
  12. // 1. 放进去:将类的实例化过程绑定到容器中
  13. // 就是将类实例化的方法存入到容器属性$instance数组中
  14. // $alias: 类实例的别名,Closure 闭包类
  15. public function bind($alias, \Closure $process)
  16. {
  17. // 将类实例化的方法绑定/存储到服务容器中
  18. $this->instance[$alias] = $process;
  19. }
  20. // 2. 取出来:执行容器中的实例化方法
  21. public function make($alias, $params = [])
  22. {
  23. // 调用回调函数,本实例即返回实例化方法的结果
  24. return call_user_func_array($this->instance[$alias], []);
  25. }
  26. }
  27. // 实例化容器
  28. $container = new Container();
  29. // 将模型对象和视图对象绑定到容器中
  30. $container->bind('model', function () {
  31. return new Model();
  32. });
  33. $container->bind('view', function () {
  34. return new View();
  35. });
  36. // 3. 创建控制器
  37. class Controller4
  38. {
  39. public function index(Container $container)
  40. {
  41. // 获取数据
  42. $data = $container->make('model')->getData();
  43. // 渲染模板
  44. return $container->make('view')->fetch($data);
  45. }
  46. }
  47. // 4. 客户端调用
  48. $controller = new Controller4();
  49. echo $controller->index($container);
  50. ?>

6. Facade门面

  1. <?php
  2. namespace mvc;
  3. // 1. 加载模型
  4. require 'Model.php';
  5. // 2. 加载视图
  6. require 'View.php';
  7. // 添加服务容器层
  8. class Container1
  9. {
  10. // 容器属性,就是一个数组,保存着创建对象的方法
  11. protected $instance = [];
  12. // 1. 放进去:将类的实例化过程绑定到容器中
  13. // 就是将类实例化的方法存入到容器属性$instance数组中
  14. // $alias: 类实例的别名,Closure 闭包类
  15. public function bind($alias, \Closure $process)
  16. {
  17. // 将类实例化的方法绑定/存储到服务容器中
  18. $this->instance[$alias] = $process;
  19. }
  20. // 2. 取出来:执行容器中的实例化方法
  21. public function make($alias, $params = [])
  22. {
  23. // 调用回调函数,本实例即返回实例化方法的结果
  24. return call_user_func_array($this->instance[$alias], []);
  25. }
  26. }
  27. // 实例化容器
  28. $container = new Container1();
  29. // 将模型对象和视图对象绑定到容器中
  30. $container->bind('model', function () {
  31. return new Model();
  32. });
  33. $container->bind('view', function () {
  34. return new View();
  35. });
  36. // 添加Facade门面类
  37. class Facade
  38. {
  39. protected static $container = null;
  40. protected static $data = [];
  41. // 用服务容器将静态属性初始化
  42. public static function initialize(Container1 $container)
  43. {
  44. static::$container = $container;
  45. }
  46. // 用静态代理方式将模型类中的getData()静态化
  47. public static function getData()
  48. {
  49. static::$data = static::$container->make('model')->getData();
  50. }
  51. // 用静态代理方式将视图类中的fetch()静态化
  52. public static function fetch()
  53. {
  54. return static::$container->make('view')->fetch(static::$data);
  55. }
  56. }
  57. // 声明一个学生类继承门面类
  58. class Student extends Facade
  59. {
  60. }
  61. // 3. 创建控制器
  62. class Controller5
  63. {
  64. // 使用构造方法,自动调用Facade里面的初始化方法
  65. public function __construct(Container1 $container)
  66. {
  67. Student::initialize($container);
  68. }
  69. public function index()
  70. {
  71. // 获取数据
  72. Student::getData();
  73. // 渲染模板
  74. return Student::fetch();
  75. }
  76. }
  77. // 4. 客户端调用
  78. $controller = new Controller5($container);
  79. echo $controller->index();
  80. ?>



三、总结

后期静态绑定是在类成员被调用的时候动态的绑定。
MVC就是控制器接受请求后,调用模型中的数据,通过视图将页面渲染出来。
通过依赖注入可以降低耦合度。
服务容器就是将类的实例化给包装到一个类中,即通过调用类中的方法,将类的实例化方法存进来,再取出去调用。
Facade门面就是通过静态代理方式将要实例化的类中的方法静态化,大大降低了耦合度。

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议