Blogger Information
Blog 27
fans 0
comment 0
visits 17331
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
028-12月04日-PHP第18节-静态类、MVC框架、依赖注入等
冇忉丼
Original
638 people have browsed it

1. 将课堂源代码, 全部写一遍, 在编辑器中写就可, 必须全部运行正确, 并加上自己理解的注释,不用手写

1.静态类

所谓静态,指以static关键字修饰的,包括类,方法。
静态类访问方法:

1、静态方法不需要实例化对象,可以通过类名直接调用,操作符为双冒号::

2、外部访问公共属性或方法(与普通类一样):

  1. $car->speed;$car->speedUp();

3、内部访问公共属性和方法(与普通类一样):

  1. $this->speed;$this->speedUp();

4、外部访问静态属性或方法:

  1. Car::getName();Car::$price;

5、内部访问静态属性:(可用延迟调用—static代替self)

  1. self::$price;

6、继承类时,子类内部调用父类静态属性:

  1. parent::$price;
  2. class Controller_article extends Controller_basepage {
  3. function __construct() {
  4. parent::__construct();
  5. }
  6. }

静态类的需求:

  1. 静态的变量或者是函数是保存的静态内存中的,只有到程序结束时才会被释放,那他是什么时候赋值的呢:是在编译的时候,动态类是在程序运行的时候动态分配的。如果类中调用一次,静态类在编译的时候需要多做工作,动态类在执行的时候需要多做工作,然而php是动态语言,每一次这两步都不掉,所以对于只运行一次的类,无所谓谁快谁慢。
  2. 但是如果一个类在程序当中要**多次调用**就不一样了,静态类是编译的时候就赋值了,程序之后的运行都可以直接调用过来,而不用动态的分配内存了,就节约了时间,这就是为什么静态类比动态类快的原因(前提是调用多次)。
  1. <?php
  2. //demo1
  3. namespace _1204;
  4. use PDO; //静态类,全局
  5. class Db1{
  6. protected static $pdo;//static使方法属性等不用实例化就可用类调用,既然如此,一般声明为
  7. //protected
  8. protected static $dsn = 'mysql:host=localhost;dbname=anguoguo';
  9. protected static $username = 'root';
  10. protected static $password = 'root';
  11. //静态方法
  12. public static function connect(){
  13. //类中访问当前类的静态成员:self::
  14. self::$pdo = new PDO(self::$dsn,self::$username,self::$password);
  15. }
  16. //测试方法
  17. public static function select(){
  18. self::connect();
  19. return self::$pdo->query('select * from `users`',PDO::FETCH_ASSOC);
  20. }
  21. }
  22. $result = Db1::select();
  23. foreach($result as $r){
  24. echo '<pre>' . print_r($r,true) . '</pre>';
  25. }
  1. <?php
  2. //demo2延迟调用
  3. namespace _1204;
  4. use PDO;
  5. class Db2{
  6. protected static $pdo;
  7. protected static $dsn = 'mysql:host=localhost;dbname=anguoguo';
  8. protected static $username = 'root';
  9. protected static $password = 'root';
  10. public static function connect(){
  11. static ::$pdo = new PDO(static::$dsn,static::$username,static::$password);
  12. //延迟绑定,动态绑定
  13. }
  14. public static function select(){
  15. static ::connect();
  16. return self::$pdo->query('select * from `users`',PDO::FETCH_ASSOC);
  17. }
  18. }
  19. class Sub extends Db2{
  20. protected static $username = 'root';
  21. protected static $password = '123';
  22. public static function connect(){
  23. self ::$pdo = new PDO(self::$dsn,self::$username,self::$password);
  24. //alt+j选择所有后面相同的单词
  25. }
  26. }
  27. $result = Db1::select();
  28. foreach($result as $r){
  29. echo '<pre>' . print_r($r,true) . '</pre>';
  30. }

mvc框架

mvc是一种常见设计模式,包括:model(模型),view(视图),controller(控制器)
Model:数据表(此处直接用数组来模拟)

  1. <?php
  2. namespace mvc;
  3. // 模型类:用于数据表的操作
  4. class Model
  5. {
  6. public function getData()
  7. {
  8. // 用二维数组模拟数据表中信息
  9. return [
  10. ['id'=>1, 'name'=>'苹果电脑', 'model'=>'MacBook Pro', 'price'=>25800],
  11. ['id'=>2, 'name'=>'华为手机','model'=>'P30 Pro','price'=>4988],
  12. ['id'=>3, 'name'=>'小爱同学','model'=>'AI音箱','price'=>299],
  13. ];
  14. }
  15. }

View: 渲染数据,向用户显示模型的数据。视图知道如何访问模型的数据,但它不知道这些数据意味着什么,也不知道用户可以做什么来操作它。

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

Controller:存在于视图和模型之间。它侦听视图(或其他外部源)触发的事件,并对这些事件执行适当的响应,并调用模型上的方法。由于视图和模型是通过通知机制连接的,因此此操作的结果将自动反映在视图中。
demo1:

  1. <?php
  2. // 控制器: 将商品信息表展示出来
  3. namespace mvc;
  4. // 1. 加载模型
  5. require 'Model.php';
  6. // 2. 加载视图
  7. require 'View.php';
  8. // 3. 创建控制器
  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();

demo1类中实例化外部类,耦合度太高
所以以下demo2将模型与视图的实例化代码从控制器分离出来, 放到了客户端,使用依赖注入,外部实例化调用的类的实例,内部方法传入调用的实例为参数

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

demo3:将依赖注入点改在控制器的构造方法中,这样多个方法调用两个实例时就很方便了

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

demo4:创建一个容器类,分两步—1.将多个类实例绑定别名,多个类方法绑定到闭包,自然这些参数就需要放到数组里;2.取出来: 执行容器中的实例方法(使用了回调函数)

  1. <?php
  2. // 控制器: 将商品信息表展示出来
  3. // 依赖注入: 将注入点改到了控制器的构造方法中
  4. namespace mvc;
  5. // 1. 加载模型
  6. use BaconQrCode\Common\Mode;
  7. require 'Model.php';
  8. // 2. 加载视图
  9. require 'View.php';
  10. /**************************************************/
  11. //添加服务容器层
  12. class Container
  13. {
  14. // 容器属性, 就是一个数组,里面全是创建对象的方法
  15. protected $instance = [];
  16. // 1. 放进去: 将类的实例化过程绑定到容器中
  17. // $alias: 类实例的别名,
  18. public function bind($alias, \Closure $process)
  19. {
  20. // 将类实例化的方法绑定/ 存储到服务容器中
  21. $this->instance[$alias] = $process;
  22. }
  23. // 2. 取出来: 执行容器中的实例方法
  24. public function make($alias, $params=[])
  25. {
  26. return call_user_func_array($this->instance[$alias], []);
  27. }
  28. }
  29. // 实例化容器
  30. $container = new Container();
  31. // 用到模型对象, 视图对象,将它们绑定到容器中
  32. $container->bind('model', function () {return new Model();});
  33. $container->bind('view', function () {return new View();});
  34. /**************************************************/
  35. // 3. 创建控制器
  36. class Controller4
  37. {
  38. public function index(Container $container)
  39. {
  40. // 3.1 获取数据
  41. $data = $container->make('model')->getData();
  42. // 3.2 渲染模板
  43. return $container->make('view')->fetch($data);
  44. }
  45. }
  46. // 4. 客户端调用/访问类成员
  47. // 将模型对象与视图对象,以参数的方式再次注入到控制器的方法
  48. $controller = new Controller4();
  49. echo $controller->index($container);

demo5: 此例使用了Facade技术,其规范/统一了对外部对象的调用方式, 全部改为了静态调用, 不管之前的方法是什么类型

  1. <?php
  2. // 控制器: 将商品信息表展示出来
  3. // Facade技术: 规范/统一了对外部对象的调用方式, 全部改为了静态调用, 不管之前的方法是什么类型
  4. namespace mvc;
  5. // 1. 加载模型
  6. use BaconQrCode\Common\Mode;
  7. require 'Model.php';
  8. // 2. 加载视图
  9. require 'View.php';
  10. /**************************************************/
  11. //添加服务容器层
  12. class Container1
  13. {
  14. // 容器属性, 就是一个数组,里面全是创建对象的方法
  15. protected $instance = [];
  16. // 1. 放进去: 将类的实例化过程绑定到容器中
  17. // $alias: 类实例的别名,
  18. public function bind($alias, \Closure $process)
  19. {
  20. // 将类实例化的方法绑定/ 存储到服务容器中
  21. $this->instance[$alias] = $process;
  22. }
  23. // 2. 取出来: 执行容器中的实例方法
  24. public function make($alias, $params=[])
  25. {
  26. return call_user_func_array($this->instance[$alias], []);
  27. }
  28. }
  29. // 实例化容器
  30. $container = new Container1();
  31. // 用到模型对象, 视图对象,将它们绑定到容器中
  32. $container->bind('model', function () {return new Model();});
  33. $container->bind('view', function () {return new View();});
  34. /**************************************************/
  35. // 添加Facade门面类
  36. class Facade
  37. {
  38. protected static $container = null;
  39. protected static $data = [];
  40. // 用服务容器给它初始化
  41. public static function initialize(Container1 $container)
  42. {
  43. static::$container = $container;
  44. }
  45. // 用静态代理方式将模型中的getData()静态化
  46. public static function getData()
  47. {
  48. static::$data = static::$container->make('model')->getData();
  49. }
  50. // 用静态代理方式将视图中的fetch()静态化
  51. public static function fetch()
  52. {
  53. return static::$container->make('view')->fetch(static::$data);
  54. }
  55. }
  56. // 声明一学生类
  57. class Son extends Facade
  58. {
  59. //
  60. }
  61. /**************************************************/
  62. // 3. 创建控制器
  63. class Controller5
  64. {
  65. public function __construct(Container1 $container)
  66. {
  67. // 调用Faceda里面的初始化方法
  68. Son::initialize($container);
  69. }
  70. public function index()
  71. {
  72. // 3.1 获取数据
  73. Son::getData();
  74. // 3.2 渲染模板
  75. return Son::fetch();
  76. }
  77. }
  78. // 4. 客户端调用/访问类成员
  79. // 将模型对象与视图对象,以参数的方式再次注入到控制器的方法
  80. $controller = new Controller5($container);
  81. echo $controller->index();

2. 将最后一个demo5.php中的代码, 手写提交


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
Author's latest blog post