Correction status:Uncorrected
Teacher's comments:
<?php
//模型实现两个功能
//1、连接数据库
//2、定义获取数据的方法
namespace mvc;
use PDO;
//1、创建类
class Model
{
//2、添加类成员
//2.1 添加类属性 数据库连接对象
public $pdo;
public function connect()
{
//配置数据库连接参数
$dsn = 'mysql:host=localhost;dbname=edu';
$username = 'root';
$password = '111';
//连接数据库
$this->pdo = new PDO($dsn, $username, $password);
}
public function getData()
{
//首先连接数据库
$this->connect();
//从数据库拿到数据
$data = $this->pdo->query('SELECT * FROM `student`')->fetchAll(PDO::FETCH_ASSOC);
//返回数据
return $data;
}
}
<?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><th>电 话</th>
<th>邮 箱</th></tr>';
foreach ($data as $student) {
$table .= '<tr>';
$table .= '<td>' . $student['id'] . '</td>';
$table .= '<td>' . $student['name'] . '</td>';
$table .= '<td>' . $student['sex'] . '</td>';
$table .= '<td>' . $student['age'] . '</td>';
$table .= '<td>' . $student['mobile'] . '</td>';
$table .= '<td>' . $student['email'] . '</td>';
$table .= '</tr>';
}
$table .= '</table>';
//返回视图
return $table;
}
}
//模板简单样式:
echo '<style>
table {border-collapse: collapse; margin:auto; text-align:center;border: 1px solid; width: 600px;height: 260px}
caption {font-size: 1.3rem; margin-bottom: 10px;}
tr:first-of-type { background-color:lightblue;}
td,th {border: 1px solid}
td:first-of-type {text-align: center}
</style>';
<?php
// 控制器: 将学生信息表展示出来
//增加服务层容器类
// 使用Facade技术: 规范/统一了对外部对象的调用方式, 全部改为了静态调用, 不管之前的方法是什么类型
namespace mvc;
use Closure;
// 1. 加载模型
require 'Model.php';
// 2. 加载视图
require 'View.php';
//添加服务容器层
class Container
{
// 容器属性, 就是一个数组,里面全是创建对象的方法
protected $instance = [];
// 1. 放进去: 将类的实例化过程绑定到容器中
// $alias: 类实例的别名,
public function bind($alias, \Closure $process)
{
// 将类实例化的方法绑定/ 存储到服务容器中
$this->instance[$alias] = $process;
}
// 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();});
// 添加Facade门面类
class Facade
{
//受保护的静态容器对象$container 和 提供给视图的数据$data = []
protected static $container = null;
protected static $data = [];
// 用服务容器给它初始化
public static function initialize(Container $container)
{
static::$container = $container;
}
// 用静态代理方式将模型中的getData()静态化
public static function getData()
{
//make()是容器类Container中的方法,用其实例对象$container来调用
//make()需要参数,是类的别名
//make()传入的参数是model,那么生成的就是Model类的实例对象,因此可以调用Model类getData()
//调用getData()获取的数据赋值给static::$data
static::$data = static::$container->make('model')->getData();
}
// 用静态代理方式将视图中的fetch()静态化
public static function fetch()
{
return static::$container->make('view')->fetch(static::$data);
}
}
// 声明一学生类
class Student extends Facade
{
//
}
// 3. 创建控制器
class Controller
{
public function __construct(Container $container)
{
// 调用Faceda里面的初始化方法
Student::initialize($container);
}
public function index()
{
// 3.1 获取数据
Student::getData();
// 3.2 渲染模板
return Student::fetch();
}
}
// 4. 客户端调用/访问类成员
// 将模型对象与视图对象,以参数的方式再次注入到控制器的方法
$controller = new Controller($container);
//使用echo 输出视图,如果没有echo,前边再怎么正确也是白费功夫,浪费时间
echo $controller->index();
Model:模型是关联数据表的,一个模型类绑定一个数据表,因此它是为视图提供获取数据的方法;
View:渲染数据,将控制器给的数据以什么样的形式展现给客户端;
Controller:获取数据,渲染模板;
但是对于三者的逻辑关系,把握还不够清晰,有时候分不清三者之间的界限。
将类实例对象放进容器中,在需要的时候调取出来,取出来的时机需要仔细琢磨。
Facade门面类可以简化类属性的访问方式,但是套马甲的原理还需要慢慢理解。