服务端 - PHP - 依赖注入与服务容器
一、依赖注入
- 原理:将本来在当前类内部对外部类的实例化过程转移至外部,消除当前类对外部类的依赖,解决代码耦合问题
1. 以外部的方法参数的形式传递到类方法中
- View
<?php
//命名空间
namespace mvctest;
//定义一个视图类:用来渲染数据
class View {
public function fetch($data) {
//使用字符串拼接的方式渲染数据
$table = '<table>';
$table .= '<caption>用户信息表</caption>';
$table .= '<tr>
<th>ID</th>
<th>用户名</th>
<th>性别</th>
<th>职位</th>
<th>邮箱</th>
<th>手机号码</th>
<th>城市</th>
<th>个性签名</th>
<th>注册时间</th>
</tr>';
//将数据循环遍历出来
foreach ($data as $staff) {
$table.='<tr>';
$table.='<td>' . $staff['id'] . '</td>';
$table.='<td>' . $staff['user_name'] . '</td>';
$table.='<td>' . $staff['sex'] . '</td>';
$table.='<td>' . $staff['position'] . '</td>';
$table.='<td>' . $staff['email'] . '</td>';
$table.='<td>' . $staff['cphone_n'] . '</td>';
$table.='<td>' . $staff['city'] . '</td>';
$table.='<td>' . $staff['signature'] . '</td>';
$table.='<td>' . date('Y年m月d日', $staff['reg_time']) . '</td>';
$table.='<tr>';
}
$table .= '</table>';
return $table;
}
}
//定义样式
echo '<style>
table {border-collapse: collapse;border: 1px solid;}
th, td{border: 1px solid; padding: 5px;}
</style>';
//调试代码
//require 'Model.php';
//echo (new View)->fetch((new Model)->getData());
- Model
<?php
//命名空间
namespace mvctest;
//定义一个模型类:用来获取数据
class Model {
public function getData() {
return (new \PDO('mysql:host=localhost;dbname=genbackmanasys', 'root', 'root'))->query('SELECT * FROM `user_info`')->fetchAll(\PDO::FETCH_ASSOC);
}
}
//调试代码
//print_r((new Model)->getData());
- Controller
<?php
//命名空间
namespace mvctest;
// 1. 加载模型类
require 'Model.php';
// 2. 加载视图类
require 'View.php';
// 3. 创建控制器类:将用户请求和数据进行关联/绑定
class Controller {
public function bind(Model $model, View $view) {
// 1. 获取数据
$data = $model->getData();
// 2. 渲染模板/视图
return $view->fetch($data);
}
}
//客户端代码
$model = new Model;
$view = new View;
$controller = new Controller;
echo $controller->bind($model, $view);
2. 以外部的方法参数的形式传递到类的构造方法中,实现对象的共享
- View
<?php
//命名空间
namespace mvctest;
//定义一个视图类:用来渲染数据
class View {
public function fetch($data) {
//使用字符串拼接的方式渲染数据
$table = '<table>';
$table .= '<caption>用户信息表</caption>';
$table .= '<tr>
<th>ID</th>
<th>用户名</th>
<th>性别</th>
<th>职位</th>
<th>邮箱</th>
<th>手机号码</th>
<th>城市</th>
<th>个性签名</th>
<th>注册时间</th>
</tr>';
//将数据循环遍历出来
foreach ($data as $staff) {
$table.='<tr>';
$table.='<td>' . $staff['id'] . '</td>';
$table.='<td>' . $staff['user_name'] . '</td>';
$table.='<td>' . $staff['sex'] . '</td>';
$table.='<td>' . $staff['position'] . '</td>';
$table.='<td>' . $staff['email'] . '</td>';
$table.='<td>' . $staff['cphone_n'] . '</td>';
$table.='<td>' . $staff['city'] . '</td>';
$table.='<td>' . $staff['signature'] . '</td>';
$table.='<td>' . date('Y年m月d日', $staff['reg_time']) . '</td>';
$table.='<tr>';
}
$table .= '</table>';
return $table;
}
}
//定义样式
echo '<style>
table {border-collapse: collapse;border: 1px solid;}
th, td{border: 1px solid; padding: 5px;}
</style>';
//调试代码
//require 'Model.php';
//echo (new View)->fetch((new Model)->getData());
- Model
<?php
//命名空间
namespace mvctest;
//定义一个模型类:用来获取数据
class Model {
public function getData() {
return (new \PDO('mysql:host=localhost;dbname=genbackmanasys', 'root', 'root'))->query('SELECT * FROM `user_info`')->fetchAll(\PDO::FETCH_ASSOC);
}
}
//调试代码
//print_r((new Model)->getData());
- Controller
<?php
//命名空间
namespace mvctest;
// 1. 加载模型类
require 'Model.php';
// 2. 加载视图类
require 'View.php';
// 3. 创建控制器类:将用户请求和数据进行关联/绑定
class Controller {
//保存初始化后的数据
private $model;
private $view;
//初始化操作
public function __construct(Model $model, View $view)
{
$this->model = $model;
$this->view = $view;
}
public function bind() {
// 1. 获取数据
$data = $this->model->getData();
// 2. 渲染模板/视图
return $this->view->fetch($data);
}
public function bind1() {
// 1. 获取数据
$data = $this->model->getData();
// 2. 渲染模板/视图
return $this->view->fetch($data);
}
}
//客户端代码
$model = new Model;
$view = new View;
$controller = new Controller($model, $view);
echo $controller->bind1();
二、服务容器
原理:创建服务容器统一管理类实例,再使用依赖注入的方式将服务容器传入到控制器中,在控制器中调用服务容器的方法操作对象
View
<?php
//命名空间
namespace mvctest;
//定义一个视图类:用来渲染数据
class View {
public function fetch($data) {
//使用字符串拼接的方式渲染数据
$table = '<table>';
$table .= '<caption>用户信息表</caption>';
$table .= '<tr>
<th>ID</th>
<th>用户名</th>
<th>性别</th>
<th>职位</th>
<th>邮箱</th>
<th>手机号码</th>
<th>城市</th>
<th>个性签名</th>
<th>注册时间</th>
</tr>';
//将数据循环遍历出来
foreach ($data as $staff) {
$table.='<tr>';
$table.='<td>' . $staff['id'] . '</td>';
$table.='<td>' . $staff['user_name'] . '</td>';
$table.='<td>' . $staff['sex'] . '</td>';
$table.='<td>' . $staff['position'] . '</td>';
$table.='<td>' . $staff['email'] . '</td>';
$table.='<td>' . $staff['cphone_n'] . '</td>';
$table.='<td>' . $staff['city'] . '</td>';
$table.='<td>' . $staff['signature'] . '</td>';
$table.='<td>' . date('Y年m月d日', $staff['reg_time']) . '</td>';
$table.='<tr>';
}
$table .= '</table>';
return $table;
}
}
//定义样式
echo '<style>
table {border-collapse: collapse;border: 1px solid;}
th, td{border: 1px solid; padding: 5px;}
</style>';
//调试代码
//require 'Model.php';
//echo (new View)->fetch((new Model)->getData());
- Model
<?php
//命名空间
namespace mvctest;
//定义一个模型类:用来获取数据
class Model {
public function getData() {
return (new \PDO('mysql:host=localhost;dbname=genbackmanasys', 'root', 'root'))->query('SELECT * FROM `user_info`')->fetchAll(\PDO::FETCH_ASSOC);
}
}
//调试代码
//print_r((new Model)->getData());
- Controller
<?php
//命名空间
namespace mvctest;
// 1. 加载模型类
require 'Model.php';
// 2. 加载视图类
require 'View.php';
// 3. 创建服务容器类:统一管理类实例
class Container {
// 1. 创建对象容器
protected $box = [];
// 2. 创建绑定方法:向对象容器中添加一个类实例
public function bind($var, \Closure $process) {
//对象容器中的键是对象名,值是其实例化过程
$this->box[$var] = $process;
}
// 3. 创建取出方法:从容器中取出一个类实例(new的过程)
public function make($var, $params = []) {
//用回调方式返回一个对象
return call_user_func_array($this->box[$var], []);
}
}
// 3. 创建控制器类:将用户请求和数据进行关联/绑定
class Controller {
public function bind(Container $container) {
// 1. 获取数据
$data = $container->make('model')->getData();
// 2. 渲染模板/视图
return $container->make('view')->fetch($data);
}
}
//客户端代码
// 1. 创建服务容器
$container = new Container;
// 2. 绑定
$container->bind('model', function() {return new Model;});
$container->bind('view', function() {return new View;});
// 3. 使用依赖注入的方式将容器传入到控制器中
$controller = new Controller();
echo $controller->bind($container);
四、课程总结
- 今天学习了 PHP 的依赖注入和服务容器,通过上课认真听讲和认真完成老师布置的作业,使得我对 依赖注入与服务容器 的理解和运用更加深入和熟悉。最主要的知识点是明白和掌握了依赖注入和服务容器的特点以及它们的基本用法。