mvc原理与依赖注入

 
<?
//模型层:当前页面要显示的数据

$pdo = new PDO('mysql:host=localhost;dbname=16','root','3.1415926',[PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING]);
$users = $pdo->query('SELECT `id`,`gender`,`uname`,`c_time` FROM `user` order by id asc LIMIT 10')->fetchAll(PDO::FETCH_ASSOC);
?>

 <!-- 视图层 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据显示</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <table border="1" cellspacing="0" cellpadding="5" align="center">
        <caption>用户信息表</caption>
        <thead>
            <tr align="center">
                <td>编号</td>
                <td>姓名</td>
                <td>性别</td>
                <td>创建时间</td>
                <td>操作</td>
            </tr>
        </thead>
        <tbody>
            <?php foreach($users as $user):?>
                <tr align="center">
                    <td><?= $user['id']?></td>
                    <td><?= $user['uname']?></td>
                    <td><?= $user['gender']==1 ? '男': '女'?></td>
                    <td><?= date("Y-m-d H:i:s",$user['c_time'])?></td>
                    <td><button>删除</button> <button>编辑</button></td>  
                </tr>
            <?php endforeach;?>     
        </tbody>
        </table>
        
</body>
</html>
<!-- 分离,就是要减少耦合,也就是说,不要在页面上进行数据访问和处理,也不要在业务层试图控制页面的现实逻辑。划分清二者的职责 -->

  

<?php

namespace mvc_demo;  
// require 'Model.php';  
  
class View{  
    public function fetch($data)  
    {  
        $table = '<table>'; // 初始化表格  
        $table .= '<caption>用户信息表</caption>'; // 添加表头标题  
        $table .= '  
        <tr align="center">  
            <td>编号</td>  
            <td>姓名</td>  
            <td>性别</td>  
            <td>创建时间</td>  
            <td>操作</td>  
        </tr>  
        ';  
        foreach($data as $user)  
        {  
            $user['gender'] = $user['gender'] == 1 ? '男' : '女'; // 注意移除了性别后的空格  
            $table .= '<tr>';  
            $table .= '<td>'.$user['id'].'</td>';  
            $table .= '<td>'.$user['uname'].'</td>';  
            $table .= '<td>'.$user['gender'].'</td>';  
            $table .= '<td>'.date("Y-m-d H:i:s", $user['c_time']).'</td>'; // 修正了日期格式中的分钟占位符  
            $table .= '<td><button>删除</button> <button>编辑</button></td>';  
            $table .= '</tr>';  
        }  
        $table .= '</table>'; // 闭合表格  
        return $table;  
    }  
}  
  
echo '<style>  
table {border-collapse: collapse; border: 1px solid; text-align: center; 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>';  
  
// 假设Model类中的方法名已经更正为getData()  
// $data = (new Model)->getData();
// echo (new View)->fetch($data); 
  

?>

  

<?php
namespace mvc_demo;
use PDO;
class Model
{
    public function getData()
    {
         return(new PDO('mysql:host=localhost;dbname=16','root','3.1415926',
        [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING]))->query('SELECT `id`,`gender`,`uname`,`c_time` FROM `user`order by id asc LIMIT 10')->fetchALL(PDO::FETCH_ASSOC);
    }
    public function editData()
    {
        
    }
}
// print_r((new Model)->getData());

?>

  

<?php
// mvc这种架构模式 ur1地址都会映射到控制器下面的具体操作方法上
class User{
    function index($id,$name)
    {
        return "您好 $name,您的id是 $id";
    }
}
function getName()
{
    return '你好呀';
}
// var_dump($_SERVER['PATH_INFO']);//string(11) "/User/index"
$arr = array_values(array_filter(explode("/",$_SERVER['PATH_INFO'])));
// var_dump($arr);//array(2) { [0]=> string(4) "User" [1]=> string(5) "index" }
$controller = __NAMESPACE__.'\\'.array_shift($arr);
// echo $controller;
$action = array_shift($arr);
// echo $action;

$params = ['id'=>1,'name'=>''];

echo call_user_func_array([(new $controller),$action],$params);

?>

  

<?php
namespace mvc_demo;
/**
 * facade门面为容器中的(动态)类提供了一个静态调用接口,相比于传统的静态方法调用,带啦了个好的可测试性和可扩展性。
 * facade就是在服务器和控制器之间加了一个中间层
 */
require 'Container.php';
class Facade{
    // 为容器中的动态类提供一种静态调用接口
    protected static $container;
    public static function initialize(Container $container)
    {
        static::$container = $container;
    }
}



?>

  

<?php
//控制器层  中间层 协调 m v的中间桥梁
namespace mvc_demo;
require 'Facade.php';


// 模型类成员getData()的访问静态化 
class FacadeModel extends Facade
{
    public static function getData()
    {
        return static::$container->make('model')->getData();
    }
}


class FacadeView extends Facade{
    public static function fetch($data)
    {
        return static::$container->make('view')->fetch($data);
    }
}





class Controller{
    

    public function __construct($container)
    {
       Facade::initialize($container);

    }

    public function index()
    {
         // 1. 获取数据 
       $data =  FacadeModel::getData();

       // 2. 渲染数据
       return FacadeView::fetch($data);
    }
   
}


// 客户端代码

$C = new Controller($container);
echo $C->index();

  

<?php
//控制器层  中间层 协调 m v的中间桥梁
namespace mvc_demo;
require 'Container.php';
class Controller{
    protected $container;

    public function __construct($container)
    {
        $this->container = $container;

    }

    public function index()
    {
         // 1. 获取数据 
       $data =  $this->container->make('model')->getData();

       // 2. 渲染数据
       return $this->container->make('view')->fetch($data);
    }

    public function edit()
    {
        $this->container->make('model')->editData();
    }
}


$C = new Controller($container);
echo $C->index();

  

<?php
// 控制器层 中间层 协调  m v 的中间桥梁
namespace mvc_demo;
require 'Model.php';
require 'View.php';
// class Controller
// {
//   
//     public function index (Model $model,View $view)
//     {
//         // 1.获取数据
//         $data = $model->getData();
//         // 2.渲染数据
//         return $view->fetch($data);
//     }

//     public function edit(Model $model)
//     {

//     }

// }
class Controller
{
    protected $model;
    protected $view;
    // 将外部依赖对象在构造方法中注入进来 完成外部对象在本类多个方法中的共享
    public function __construct(Model $model, view $view)
    {
       $this->model=$model;
       $this->view = $view;
    }

    public function index ()
    {
        // 1.获取数据
        $data = $this-> model->getData();
        // 2.渲染数据
        return $this-> view->fetch($data);
    }

    public function edit()
    {
        $this->model->editData();
    }

}
$model = new Model;
$view = new View;
$c = new Controller($model,$view);
echo $c->index();

// -----------------------------------------------------------
// 如果当前所依赖的外部对象过多,名称过长 将依赖的所有外部对象放到一个容器中统一管理,并且还可以起别名
?>

  

<?php
/**
 * 容器 container 依赖注入的类 统一由容器进行管理,容器 数组
 * 如果当前类的依赖对象过多,可能将这些依赖的对象,类,闭包,放到一个”服务器“中进行统一管理 bind make
 */

 namespace mvc_demo;
 use Closure;

  //类的加载 可升级为自动加载
  require 'Model.php';
  require 'View.php';
 

//  服务容器 一个自动生产类/对象的工厂
class Container{
    //对象容器
    protected $instances =[];
   /**
    * 绑定一个类,闭包,实例,接口实现到容器
    *@access public
    *@param string|array $abstract 类标识或者接口的别名 alias
    *@param mixed $concrete 要绑定的类,闭包,或者实例
    */
    
    // 

    public function bind($abstract ,Closure $concrete)
    {
        $this->instances[$abstract] = $concrete;

    }
    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;
});

?>

  

posted @ 2024-08-20 19:28  好好学习天天向上上上  阅读(3)  评论(0编辑  收藏  举报