Blogger Information
Blog 39
fans 0
comment 0
visits 34193
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
容器与门面、路由的原理与实现--2019/08/07
LISTEN的博客
Original
818 people have browsed it

1、mvc与容器:

model.php

实例

<?php
// 模型类: 用于数据库操作,数据访问

class Model
{
    protected $pdo;
    protected $name;
    public function __construct($name='')
    {
//        $this->name=$name;
//        echo 'name: '.$this->name;
//        die;
        $this->pdo=new \PDO('mysql:host=localhost;dbname=listen0724','root','root');
    }

    public function getData()
    {
        $sql='select `detail_id`,`name`,concat(left(`detail`,30),\'...\') as `detail` from `details`';
        $stmt=$this->pdo->prepare($sql);
        $stmt->execute();
        $res=$stmt->fetchAll(\PDO::FETCH_ASSOC);
        return $res;
    }
}

运行实例 »

点击 "运行实例" 按钮查看在线实例


view.php

实例

<?php
// 视图类: 渲染数据

class View
{
    public function fetch($data)
    {
        $table = '<table border="1" cellspacing="0" align="center" cellpadding="3" width="800" style="text-align: center">';
        $table .= '<caption>信息列表</caption>';
        $table.=' <thead><tr bgcolor="#00F7DE"><th>序号</th><th>名称</th><th>详情</th></tr></thead>';
        $table.= '<tbody >';

        foreach ($data as $detail){
            $table.='<tr>';
            $table.='<td>'.$detail['detail_id'].'</td>';
            $table.='<td>'.$detail['name'].'</td>';
            $table.='<td>'.$detail['detail'].'</td>';
            $table.='</tr>';
        }
        $table.='</tbody></table>';

        return $table;

    }
}

运行实例 »

点击 "运行实例" 按钮查看在线实例

demo1.php  容器

实例

<?php

//容器: 类与类实例的集合, 至少包括类实例的绑定与创建二个功能
// 容器也是一个类,至少要提供二个功能: 创建类实例, 取出类实例

require 'Model.php';
require 'View.php';

// 创建容器类
class Container
{
    // 类实例数组,对象池
    protected $instance=[];

    // 将某个类的实例绑定到容器中,生成类实例
    public function bind($className,Closure $process)  // $process 用回调闭包函数实例类
    {
        // 将类实例保存到容器中
        if(!isset($this->instance[$className])){
            $this->instance[$className]=$process;

        }
    }

    // 从容器中取出对象
    public function make($className,$params=[])
    {
        //方法1:
//        $res=$this->instance[$className];
//        return $res();

        //方法2:
        return call_user_func_array($this->instance[$className],$params);
    }
}

// 将模型与视图的实例绑定到容器中
$container=new Container();

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

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

运行实例 »

点击 "运行实例" 按钮查看在线实例


2、门面

demo2.php

实例

<?php

//容器: 类与类实例的集合, 至少包括类实例的绑定与创建二个功能
// 容器也是一个类,至少要提供二个功能: 创建类实例, 取出类实例

require 'Model.php';
require 'View.php';

// 创建容器类
class Container
{
    // 类实例数组,对象池
    protected $instance=[];

    // 将某个类的实例绑定到容器中,生成类实例
    public function bind($className,Closure $process)  // $process 用回调闭包函数实例类
    {
        // 将类实例保存到容器中
        if(!isset($this->instance[$className])){
            $this->instance[$className]=$process;

        }
    }

    // 从容器中取出对象
    public function make($className,$params=[])
    {
        //方法1:
//        $res=$this->instance[$className];
//        return $res();

        //方法2:
        return call_user_func_array($this->instance[$className],$params);
    }
}

// 将模型与视图的实例绑定到容器中
$container=new Container();

$container->bind('model',function (){return new Model();});
$container->bind('view',function (){return new View();});


//* 门面: 给容器中的类方法调用,提供一个统一的静态访问接口

class Facade
{
    // 容器类的实例
    protected static $container=null;

    // 模型数据
    protected static $data=[];

    // 初始化方法
    public static function initialize(Container $container)
    {
        // static:: 后期静态绑定
        static::$container=$container;
    }

    // 为二个基本的访问创建统一的静态访问接口
    // 获取模型数据的静态接口
    public static function getData()
    {
        static::$data=static::$container->make('model')->getData();
    }

    public static function getData1($className)
    {
        static::$data=static::$container->make($className)->getData();
    }

    // 渲染模板的静态接口
    public static function fetch()
    {
        return static::$container->make('view')->fetch(static::$data);
    }

    public static function fetch1($className)
    {
        return static::$container->make($className)->fetch(static::$data);
    }
}

// 声明一个门面的子类
class Product extends Facade
{
    // ....
}



// 创建客户端的控制器
class Controller
{
    public function __construct(Container $container)
    {
        Product::initialize($container);
    }

    public function index()
    {
        //获取数据
       Product::getData();

        //渲染模板
        return Product::fetch();
    }

    public function index1()
    {
        //获取数据
        Product::getData1('model');

        //渲染模板
        return Product::fetch1('view');
    }
}

$controller=new Controller($container);
//echo $controller->index();
echo $controller->index1();

运行实例 »

点击 "运行实例" 按钮查看在线实例


改进容器门面、 demo3.php

实例

<?php
//容器: 类与类实例的集合, 至少包括类实例的绑定与创建二个功能
// 容器也是一个类,至少要提供二个功能: 创建类实例, 取出类实例

require 'Model.php';
require 'View.php';

// 创建容器类
class Container
{
    // 类实例数组,对象池
    protected $instance=[];

    // 将某个类的实例绑定到容器中,生成类实例
    public function bind($className, Closure $process)  // $process 用回调闭包函数实例类
    {
        // 将类实例保存到容器中
        if(!isset($this->instance[$className])){
            $this->instance[$className]=$process;

        }
    }

    // 从容器中取出对象
    public function make($className,$params=[])
    {
        //方法1:
//        $res=$this->instance[$className];
//        return $res();

        //方法2:
        return call_user_func_array($this->instance[$className],$params);
    }
}


//* 门面: 给容器中的类方法调用,提供一个统一的静态访问接口

class Facade
{
    // 容器类的实例
    protected static $container=null;

    // 模型数据
    protected static $data=[];

    // 初始化方法
    public static function initialize(Container $container)
    {
        // static:: 后期静态绑定
        static::$container=$container;
    }

    // 为二个基本的访问创建统一的静态访问接口
    // 获取模型数据的静态接口
    public static function getData($alias,$className,$method)
    {
        static::$container->bind($alias,function ()use($className){return new $className();});
        static::$data=static::$container->make($alias)->$method();
    }

    // 渲染模板的静态接口
    public static function fetch($alias,$className,$method)
    {
        static::$container->bind($alias,function ()use($className){  return new  $className();});
        return static::$container->make($alias)->$method(static::$data);
    }

}

// 声明一个门面的子类
class Product extends Facade
{
    // ....
}



// 创建客户端的控制器
class Controller
{
    public function __construct(Container $container)
    {
        Product::initialize($container);
    }

    public function index()
    {
        //获取数据
        Product::getData('model',Model::class,'getData');

        //渲染模板
        return Product::fetch('view',View::class,'fetch');
    }
}
// 将模型与视图的实例绑定到容器中
$container=new Container();
$controller=new Controller($container);
echo $controller->index();

运行实例 »

点击 "运行实例" 按钮查看在线实例


3、路由的原理与实现

路由与类

实例

<?php
// 1. 从pathinfo切割出独立的单元
// 2. 从pathinfo中解析出模块/控制器/操作
// 3. 从pathinfo中解析出变量键值对

// 路由的基本功能: 将URL地址pathinfo, 映射到指定的控制器方法中/函数
// 路由就是一个请求分发器

//http://php***/0807test/route.php/admin/index/hello/id/5/name/admin

//admin:模块
//index:控制器
//hello:方法
//id、name:参数
//5、admin:参数值

print_r($_SERVER['REQUEST_URI']);

$uri=$_SERVER['REQUEST_URI'];
$request=explode('/',$uri);
echo '<pre>'. print_r($request, true);

//array_slice() 函数在数组中根据条件取出一段值,并返回。
$route=array_slice($request,3,3);
//echo '<pre>'. print_r($route, true);

//list():将一个索引数组,给每一个数组值分配一个变量名,用于在一次操作中给一组变量赋值。
// list()不是函数,是一个语法结构, 函数永远不可能出现在等号左边
list($module,$controller,$action)=$route;
//$moudle = $route[0];
//$controller = $route[1];
//$action = $route[2];


// 将这三个独立变量转为关联数组
// $pathinfo['module'] = $module;
// $pathinfo['controller'] = $controller;
// $pathinfo['action'] = $action;


//compact() 函数创建一个由参数所带变量组成的数组。如果参数中存在数组,该数组中变量的值也会被获取。
//本函数返回的数组是一个关联数组,键名为函数的参数,键值为参数中变量的值。
$pathinfo=compact('module','controller','action');
echo '<pre>'. print_r($pathinfo, true);

//从Pathinfo将参数的键值对解析出来
//$arr = ['id'=>5, 'name'=>'admin'];

$values = array_slice($request, 6);

for($i=0;$i<count($values);$i+=2){
    if(isset($values[$i+1])){
        $params[$values[$i]]=$values[$i+1];
    }
}

echo '<pre>'. print_r($params, true);

// 创建一个控制器
class Index
{
    public function hello($id,$name)
    {
        return '控制器和方法名:'.__METHOD__.' ,参数: id='.$id .' , name='.$name;
    }
    public function demo($id,$name,$age)
    {
        return '控制器和方法名:'.__METHOD__.' ,参数: id='.$id .' , name='.$name.' , age='.$age;
    }
}

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

运行实例 »

点击 "运行实例" 按钮查看在线实例


路由与闭包函数

实例

<?php
// 路由的基本功能: 将URL地址pathinfo, 映射到指定的控制器方法中/函数
// 路由就是一个请求分发器

//http://php***/0807test/my_work.php/hello/id/5/name/admin

//hello:方法
//id、name:参数
//5、admin:参数值

$uri=$_SERVER['PATH_INFO'];

// 1. 从pathinfo切割出独立的单元

$request=explode('/',$uri);

echo '<pre>'. print_r($request, true);

// 2. 从pathinfo中解析出操作
$pathinfo['action']=$request[1];
echo '<pre>'. print_r($pathinfo, true);

// 3. 从pathinfo中解析出变量键值对
$values = array_slice($request, 2);
echo '<pre>'. print_r($values, true);

$pathinfo['action']=function (...$arr) use( $pathinfo ){

    for($i=0;$i<count($arr);$i+=2){
        if(isset($arr[$i+1])){
            $params[$arr[$i]]=$arr[$i+1];
        }
    }
    $str='';
    foreach ($params as $key=>$value){
        $str.=$key.'='.$value.' ';
    }
    return '方法名:'.$pathinfo['action'].' ,参数: '.$str;
};

echo call_user_func_array($pathinfo['action'],$values);

运行实例 »

点击 "运行实例" 按钮查看在线实例

Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post