Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:理解了为什么要这么写, 写起来就快多了
【编程思路】
1、对于MVC中运用服务容器和门面技术,理解重点是‘不断解耦,分层接管’;
2、把url理解为一个数组,把里面数据解析出来得到pathinfo和查询参数!
【作业总结】
本次作业主要是服务容器和门面感悟最深,这一章和接下来的“工厂”真的好抽象,但是反复学习后我应该是能理解明白了
①原始方法,直接在控制器中实例化,代码高度耦合;②依赖注入,在客户端实例化,解决对象之间的耦合;③注入到构造方法,实现依赖对象共享;④服务容器,对象容器,多个对象方便管理,抽象灵活;⑤门面,结果访问方式,更抽象更灵活!>>>总结如图:
【MVC(服务容器+门面)】
实例
<?php namespace day17; // 控制器 // 1、加载模型 require 'Model.php'; // 2、加载视图 require 'View.php'; // 3、服务容器 class Container { // 1.对象容器 protected $instances = []; // 2.向对象容器中添加类实例 public function bind($alias, \Closure $process) { $this->instances[$alias] = $process; } // 3.从对象容器取出类实例 public function make($alias, $params = []) { return call_user_func_array($this->instances[$alias], []); } } // 服务容器的实例化 $container = new Container; // 将类实例绑定到容器中 $container->bind('model_plus', function () { return new Model(); }); $container->bind('view_plus', function () { return new View(); }); // 4、增加门面类:接管对容器中的对象的访问 class Facade { // 容器属性 protected static $container = null; // 数据集合 protected static $data = []; // 初始化(理解为Facade的构造方法) public static function initialize(Container $container) { static::$container = $container; } // 动态方法包装器:将动态方法转为静态访问 public static function getData() { static::$data = static::$container->make('model_plus')->getData(); } public static function fetch() { return static::$container->make('view_plus')->fetch(static::$data); } } // 5、创建控制器 class Controller { // 构造方法中,初始化门面类Facade public function __construct(Container $container) { Facade::initialize($container); } public function index() { // 1.获取数据 Facade::getData(); // 2.渲染模板 return Facade::fetch(); } // public function test(Container $container) // { // // 1.获取数据 // $data = $container->make('model_plus')->getData(); // // // 2.渲染模板 // return $container->make('view_plus')->fetch($data); // } } // 6、客户端调用 $controller = new Controller($container); echo $controller->index();
运行实例 »
点击 "运行实例" 按钮查看在线实例
【路由解析:查询字符串方式】
<?php namespace day17; // 路由解析类 class UrlController { public function getCar($id, $name) { return "id --> $id, name --> $name"; } } // 1.解析出pathinfo $pathinfo = explode('/', $_SERVER['PATH_INFO']); $pathinfo = array_values(array_filter($pathinfo)); echo '<pre>' . print_r($pathinfo, true) . ''; echo '<hr>'; // 2.解析出控制器 $controller = __NAMESPACE__ . '\\' . ucfirst($pathinfo[0]) . 'Controller'; // 3.解析出控制器方法 $action = $pathinfo[1]; echo $action; echo '<hr>'; // 4.解析出参数 \parse_str($_SERVER['QUERY_STRING'], $params); // 实例化控制器 $url = new $controller(); // 以回调的方法来调用控制器的方法 echo call_user_func_array([$url, 'getCar'], $params);
【路由解析:pathinfo方式】
// 4.解析出参数 $values = array_slice($pathinfo, 2); $params = []; for ($i = 0; $i < count($values); $i+=2) { if (isset($values[$i+1])) $params[$values[$i]] = $values[$i+1]; } // 实例化控制器 $url = new $controller(); // 以回调的方法来调用控制器的方法 echo call_user_func_array([$url, 'getCar'], $params);