Blogger Information
Blog 38
fans 1
comment 0
visits 28653
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
12月04日_PHP类中静态成员和MVC(依赖注入、服务容器和Facade门面)
fkkf467
Original
921 people have browsed it

一、类中静态成员

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门面就是通过静态代理方式将要实例化的类中的方法静态化,大大降低了耦合度。

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:写得好, 推荐给大家了
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments