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);
点击 "运行实例" 按钮查看在线实例