Correcting teacher:PHPz
Correction status:qualified
Teacher's comments:
C: Controller(控制层),是middile层, 它负责根据用户从”视图层”输入的指令,选取”数据层”中的数据,然后对其进行相应的操作,产生最终结果。
仿站: V - M - C
容器和依赖注入
ThinkPHP使用容器来更方便的管理类依赖及运行依赖注入,新版的容器支持PSR-11规范。
容器类的工作由think\Container类完成,但大多数情况我们只需要通过app助手函数或者think\App类即可容器操作,如果在服务类中可以直接调用this->app进行容器操作。
依赖注入其实本质上是指对类的依赖通过构造器完成自动注入,例如在控制器架构方法和操作方法中一旦对参数进行对象类型约束则会自动触发依赖注入,由于访问控制器的参数都来自于URL请求,普通变量就是通过参数绑定自动获取,对象变量则是通过依赖注入生成。
依赖注入的对象参数支持多个,并且和顺序无关。
支持使用依赖注入的场景包括(但不限于):
<?php
namespace my_Model;
use PDO;
//模型层 获取数据表中数据
class Model
{
public function getData()
{
return (new PDO('mysql:host=localhost;dbname=zwz','zwz1230','a123456'))->query("SELECT `id`,`uname` FROM `user` ORDER BY `id` asc LIMIT 10")->fetchAll(PDO::FETCH_ASSOC);
}
}
print_r((new Model())->getData());
<?php
namespace my_Model;
//视图层 生成可视化表格
class View
{
public function fetch($data)
{
$table = '<table>';
$table.= '<caption>用户信息表</caption>';
$table.= '<tr><th>编号</th><th>姓名</th></tr>';
foreach ($data as $key => $user) {
$table.= '<tr>';
$table.= '<td>'.$user['id'].'</td>';
$table.= '<td>'.$user['uname'].'</td>';
$table.= '</tr>';
}
$table.= '</table>';
return $table;
}
}
echo '<style>
table {border-collapse: collapse; border: 1px solid;text-align: center; width: 500px;height: 150px;width: 600px;}
caption {font-size: 1.2rem; margin-bottom: 10px;}
tr:first-of-type { background-color:lightblue;}
td,th {border: 1px solid; padding:5px}
</style>';
<?php
namespace my_Model;
require 'Model.php';
require 'View.php';
//中间桥梁 控制器
class Controller
{
//依赖注入外部对象
public function index(Model $Model,View $View)
{
//1.获取数据
$data = $Model->getData();
//2.模板渲染
return $View->fetch($data);
}
}
$model = new Model() ;
$view = new View();
$controller = new Controller($model,$view);
echo $controller->index($model,$view);
__construct()
,可以在类方法中共享方法
<?php
namespace my_Model;
require 'Model.php';
require 'View.php';
//中间桥梁 控制器
class Controller
{
protected $Model;
protected $View;
//依赖注入 使用构造器进行传参可以在类方法中共享
public function __construct(Model $Model,View $View)
{
$this->Model = $Model;
$this->View = $View;
}
public function index(Model $Model,View $View)
{
$data = $this->Model->getData();
return $this->View->fetch($data);
}
}
$model = new Model() ;
$view = new View();
$controller = new Controller($model,$view);
//采用异步回调方式进行输出
echo call_user_func_array([$controller,"index"],[$model,$view]);
绑定
容器:container :依赖注入的类统一由容器进行管理,容器 数组
<?php
namespace my_Model;
/**
* 容器:container :依赖注入的类统一由容器进行管理,容器 数组
*
* 如果当前类依赖的对象很多, 可以将这些依赖的对象 , 类,闭包,放到一个"服务容器"中进行统一管理 bind make
*/
use Closure;
require 'Model.php';
require 'View.php';
//服务容器 : 一个自动生产类/对象的工厂
class Container
{
//1.对象容器 数组
protected $instances = [];
/**
* 2.往对象容器数组中去绑定 对象
* 绑定一个类、闭包、实例、接口实现到容器
* @access public
* @param string|array $abstract 类标识、接口的别名 alias
* @param mixed $concrete 要绑定的类、闭包或者实例
* @return $this
*/
public function bind($abstract,Closure $concrete)
{
//初始化对象容器,健是别名,键值是对象
$this->instances[$abstract] = $concrete;
}
//3. 从对象容器中取出 对象并调用
public function make($abstract,$params=[])
{
return call_user_func_array($this->instances[$abstract],$params);
}
}
$container = new Container;
//绑定一个闭包到容器 : 我们使用这个model对象的时候 再去实例化
$container->bind('model',function(){
return new Model();
});
$container->bind('view',function(){
return new View();
});
class Controller
{
public function index(Container $container)
{
$data = $container->make('model')->getData();
return $container->make('view')->fetch($data);
}
}
//客户端代码
$contrl = new Controller;
echo $contrl->index($container);
facade 门面技术 实现类成员访问静态化
// facade 门面技术
class Facade {
//为容器中的类提供一种静态调用方式
protected static $container;
public static function initialize(Container $container)
{
static::$container = $container;
}
}
//模型类成员的访问静态化
class UserModel extends Facade
{
public static function getData()
{
//后期静态绑定
return static::$container->make('model')->getData();
}
}
//视图层类成员访问静态化
class UserView extends Facade
{
public static function fetch($data)
{
//后期静态绑定
return static::$container->make('view')->fetch($data);
}
}
class Controller
{
public function __construct(Container $container)
{
Facade::initialize($container);
}
public function index()
{
$data = UserModel::getData();
return UserView::fetch($data);
}
}
//客户端代码
echo (new Controller($container))->index();