Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:理解这里面的原理就可以了, 具体实现可以有不同方案
Demo1.php 认识静态static
<?php
namespace _1204; //认识静态static
//static : 声明类中的静态成员
/*class Db1
{
// 非静态成员: 必须实例化后才能访问
// public function demo()
// {
//
// }
//
}*/
//1、创建类
use PDO;
class Db1
{
//2、添加类成员
// 添加的静态成员: 属性, 方法
protected static $pdo;
protected static $dsn = 'mysql:host=127.0.0.1;dbname=pdo';
protected static $username = 'root';
protected static $password = 'root';
//静态方法
public static function connect()
{
//在类中访问当前类的静态成员
self::$pdo = new PDO(self::$dsn,self::$username,self::$password);
}
//使用静态方法
public static function select()
{
self::connect();
return self::$pdo->query('select * from `users`',PDO::FETCH_ASSOC);
}
}
//3、访问类成员 静态调用不同实例化
$result = Db1::select();
foreach($result as $row){
echo '<pre>'.print_r($row,true).'</pre>';
}
Demo2.php 静态调用
<?php
namespace _1204;
//static: 后期静态绑定 延迟绑定
//使用场景: 静态继承的上下文环境中
//类成员访问绑定时间: 在声明的时候绑定,在调用的时候绑定
//后期绑定就是在类成员被调用的时候在动态绑定,也叫: 延迟绑定
use PDO;
class Db2
{
// 1、添加静态成员
protected static $pdo;
protected static $dsn='mysql:host=127.0.0.1;dbname=pdo';
protected static $username = 'root';
protected static $password = 'root';
public static function connect()
{
// 在类中访当前问静态成员: self::
self:: $pdo = new PDO(self::$dsn,self::$username,self::$password);
}
public static function select()
{
// 1、在子类中使用父类方法需要将self换成 static
static::connect();
return self::$pdo->query('select * from `users`',PDO::FETCH_ASSOC);
}
}
//继承Db2父类
class Sub extends Db2
{
protected static $username = 'root';
protected static $password = 'root';
// 使用子类自定义的connect方法
public static function connect()
{
self::$pdo = new PDO(self::$dsn,self::$password,self::$username);
}
}
//访问类成员
//$result = Db2::select();
$result = Sub::select();
//实际使用子类中conncet
foreach($result as $wor)
{
echo '<pre>'.print_r($wor,true).'</pre>';
}
Model.php 定义模型
<?php
namespace mvc;
//模型类: 用于数据表的操作
class Model
{
public function getData()
{
//用来模拟数组从数据表中获得商品数据
return [
['id'=>1, 'name'=>'苹果电脑', 'model'=>'MackBook Pro', 'price'=>25800],
['id'=>2, 'name'=>'华为手机', 'model'=>'MackBook Pro', 'price'=>4988],
['id'=>3, 'name'=>'小爱同学', 'model'=>'AI音箱', 'price'=>399],
];
}
}
View.php 定义视图模板
<?php
namespace mvc;
//视图类: 渲染数据
class View
{
// 创建视图模板方法
public function fetch($data)
{
$table = '<table>';
$table .= '<caption>商品信息表</caption>';
$table .= '<tr><th>ID</th><th>品名</th><th>型号</th><th>价格</th></tr>';
// 循环数据表
foreach($data as $product)
{
$table .= '<tr>';
$table .= '<td>'.$product['id'].'</td>';
$table .= '<td>'.$product['name'].'</td>';
$table .= '<td>'.$product['model'].'</td>';
$table .= '<td>'.$product['price'].'</td>';
$table .= '</tr>';
}
$table .= '</table>';
return $table;
}
}
//给表增加样式
echo '<style>
table {border-collapse: collapse;border: 1px solid; width: 500px;height: 150px}
caption {font-size: 1.2rem; margin-bottom: 10px;}
tr:first-of-type{background-color:lightblue;}
td,th {border: 1px solid}
td:first-of-type {text-align:center}
</style>';
//echo '<style>
//table {border-collapse: collapse; border: 1px solid; width: 500px;height: 150px}
//caption {font-size: 1.2rem; margin-bottom: 10px;}*/
//tr:first-of-type { background-color:lightblue;}
//td,th {border: 1px solid}
//td:first-of-type {text-align: center}
//</style>';
Demo1.php 控制器设置将表中的数据返回出来
<?php
//控制器: 将商品信息表展示出来
namespace mvc;
//1、加载模型
require 'Model.php';
//2、加载视图
require 'View.php';
//3、创建控制器
class Controller1
{
public function index()
{
// 3.1 获取数据
$model =new Model();
$data = $model->getData();
// 3.2 渲染模板
$view = new View();
return $view->fetch($data);
}
}
//4、客户端调用 : 访问类成员
$controller = new Controller1();
echo $controller->index();
Demo2.php
<?php
//控制器: 将商品信息表展示出来
//将类中的对其他类的实例化,模型/视图分离出来,降低耦合度
//依赖注入
namespace mvc;
//1、加载模型
require 'Model.php';
//2、加载视图
require 'View.php';
//3、创建控制器
class Controller2
{
public function index( Model $model,View $view) //index方法要依赖于模型对象和视图对象 怎么办?通过参数方式传入
{
//在控制器中不不应该对模型和视图进行实例化 怎么办? 拿到类的外面去
// 3.1 获取数据
// $model =new Model();
$data = $model->getData();
// 3.2 渲染模板
// $view = new View();
return $view->fetch($data);
}
}
//4、客户端调用 : 访问类成员
//将模型与视图的实例化代码从控制器中分离出来, 放到了客户端
$model = new Model();
$view = new View();
//将模型对象与视图对象,以参数的方式再次注入到控制器的方法
$controller = new Controller2();
echo $controller->index($model,$view); //'解决的耦合度
Demo3.php
<?php
//控制器: 将商品信息表展示出来
//依赖注入: 将注入点改到了控制器的构造方法中
namespace mvc;
//1、加载模型
require 'Model.php';
//2、加载视图
require 'View.php';
//3、创建控制器
class Controller3
{
protected $model;
protected $view;
//定点注入可以使用构造方法
// 添加构造器,注入点改到了构造方法中,实现了模型与视图对象的共享
public function __construct(Model $model,View $view)
{
$this->model = $model;
$this->view = $view;
}
public function index( ) //index方法要依赖于模型对象和视图对象 怎么办?通过参数方式传入
{
//在控制器中不不应该对模型和视图进行实例化 怎么办? 拿到类的外面去
// 3.1 获取数据
// $model =new Model();
$data = $this->model->getData();
// 3.2 渲染模板
// $view = new View();
return $this->view->fetch($data);
}
}
//4、客户端调用 : 访问类成员
//将模型与视图的实例化代码从控制器中分离出来, 放到了客户端
$model = new Model();
$view = new View();
//将模型对象与视图对象,以参数的方式再次注入到控制器的方法
$controller = new Controller3($model,$view);
echo $controller->index(); //'解决的耦合度
Demo4.php
<?php
//控制器: 将商品信息表展示出来
//依赖注入: 将注入点改到了控制器的构造方法中
namespace mvc;
//1、加载模型 需要使用use 模型
use BaconQrCode\Common\Mode;
require 'Model.php';
//2、加载视图
require 'View.php';
/*******************************************************************/
//添加服务容器器
class Container
{
// 容器属性,就是一个数组,里面全是创建对象的方法
protected $instance =[];
// 1、放进去: 将类的实例化过程绑定到容器中
// $alias:类实例的别名
public function bind($alias,\Closure $process)
{
//将类实例化的方法绑定/ 存储到服务器容器中
$this->instance[$alias] = $process;
// $this->instance['model'] = 'new Model()';
}
// 2、取出来: 执行容器中的实例方法
public function make($alias,$params=[])
{
return call_user_func_array($this->instance[$alias],[]);
}
}
//实例容器
$container =new Container();
//用到模型对象,视图对象,将他们绑定到容器中 在写入代码时注意 参数以及拼写
$container->bind('model',function(){return new Model();});
$container->bind('view',function(){return new View();});
//$container->bind('view', function () {return View();});
/*******************************************************************/
//3、创建控制器
class Controller4
{
public function index(Container $container ) //index方法要依赖于模型对象和视图对象 怎么办?通过参数方式传入
{
//在控制器中不不应该对模型和视图进行实例化 怎么办? 拿到类的外面去
// 3.1 获取数据
// $model =new Model();
$data = $container->make('model')->getData();
// 3.2 渲染模板
// $view = new View();
return $container->make('view')->fetch($data);
}
}
//4、客户端调用 : 访问类成员
//将模型对象与视图对象,以参数的方式再次注入到控制器的方法
$controller = new Controller4();
echo $controller->index($container); //'解决的耦合度
Facade.php 门面模式 包含了依赖依赖注入和嵌套容器
<?php
//控制器: 将商品信息表展示出来
//依赖注入: 将注入点改到了控制器的构造方法中
//Facdae技术: 规范/统一了对外部对象的调用方式,全部改为了静态调用,不管之前的方法是什么类型
namespace mvc;
//1、加载模型 使用use 完成操作
use BaconQrCode\Common\Mode;
require 'Model.php';
//2、加载视图
require 'View.php';
/*******************************************************************/
//添加服务容器器
class Container1
{
// 容器属性,就是一个数组,里面全是创建对象的方法
protected $instance =[];
// 1、放进去: 将类的实例化过程绑定到容器中
// $alias:类实例的别名
public function bind($alias,\Closure $process)
{
//将类实例化的方法绑定/ 存储到服务器容器中
$this->instance[$alias] = $process;
// $this->instance['model'] = 'new Model()';
}
// 2、取出来: 执行容器中的实例方法
public function make($alias,$params=[])
{
return call_user_func_array($this->instance[$alias],[]);
}
}
/******************************************************/
//添加Facade门面
class Facade
{
protected static $container = null;
protected static $data = [];
//用上面的容器给他初始化
public static function initialize(Container1 $container)
{
static::$container = $container;
}
//用静态代理的方法将模型中的getData()静态化
public static function getData()
{
static::$data = static::$container->make('model')->getData();
}
//用静态代理方式见视图总的fetch()静态化
public static function fetch()
{
return static::$container->make('view')->fetch(static::$data);
}
}
//声明一个学生类 : 做一个子类子
class Student extends Facade
{
// 增删改查都可以用静态方法
// 这样就能直接用子类调用
}
/******************************************************/
//实例容器
$container1 =new Container1();
//用到模型对象,视图对象,将他们绑定到容器中
$container1->bind('model',function(){return new Model();});
$container1->bind('view',function(){return new View();});
//$container->bind('view', function () {return View();});
/*******************************************************************/
//3、创建控制器
class Controller5
{
public function __construct(Container1 $container)
{
//调用Facade里面的初始化方法
Facade::initialize($container);
}
public function index() //index方法要依赖于模型对象和视图对象 怎么办?通过参数方式传入
{
//在控制器中不不应该对模型和视图进行实例化 怎么办? 拿到类的外面去
// 3.1 获取数据
// $model =new Model();
Student::getData();
// 3.2 渲染模板
// $view = new View();
return Student::fetch();
}
}
//4、客户端调用 : 访问类成员
//将模型对象与视图对象,以参数的方式再次注入到控制器的方法
$controller = new Controller5($container1);
echo $controller->index(); //'解决的耦合度
1、static静态调用访问成员,不用实例化!使用self 不能使用$this,成员也是static
2、模型用来设置操作数据表的,将模型和视图放在同命名空间下,不能使用同样的类
3、创建容器后可以不用在类中,实例化模型和和视图,维护更放心,代码优化
4、Facade门面 使用将常用的操作方法封装成静态,然后用子类调用