10月11日:
1. 写一个依赖注入的案例, 内容自定义
2. 写一个mvc应用的案例, 内容自定义
3. 写一个简单的路由, 理解路由的原理与目标
用户使用浏览器访问php构建的web应用时,都是通过url来获得指定页面的内容。而对应用的所有请求都会定向到应用入口文件(一般是单一入口),系统会从URL参数中解析当前请求的模块、控制器、操作方法以及参数,就可以执行到相应的代码。
结合MVC的设计模式,使用php路由机制,完全可以搭建一个url驱动运行的应用系统,这个系统可以是单一串联结构的MVC,也可以构成几个MVC结构并联的结构。
MVC的工作流程如下:
1. 浏览者->发出指令,后台调用控制器处理
2. 控制器->按指令选取一个合适的模型 (动作集)
3. 模型->按照控制器指令选取相应的数据 (功能集)
4. 控制器->按指令选取相应的视图
5. 视图->把第三步取到的数据按用户想要的样子显示出来 (显示集)
实例说明:
【1】编写一个Router.php来解析url。以系统默认的URL模式(PATHINFO模式)来解析内容,例如:http://serverName/index.php/Home/Index/index系统会访问默认模块(Home)下面的默认控制器(Index)的默认操作(index);
【2】编写一个自动加载文件AutoLoad.php,实现所有类的动态懒加载;
【3】编写一个入口文件index.php,在此按照url解析的模块、控制器和方法去执行。依赖注入和服务容器需要在这个文件中添加代码;
【4】编写一个控制器文件controller.php,url中的请求会通过这里派发到model去实现功能,返回来的数据再发送view去显示;这里主要是逻辑处理的操作;
【5】编写model.php,这里主要实现业务的功能,比如数据库操作、方法库等与数据资源相关的操作;
【6】编写view.php,这里主要功能是把获得的数据资源展示给用户,实际项目中更多是与html/js相关的内容。
代码实现:
实例 -- Router.php
<?php
class Router {
public static $module;
public static $controller = 'controller';
public static $action = 'index';
public static $params = [];
public static function getRoute($curentFile) {
$req = explode('/', $_SERVER['REQUEST_URI']);
$file = explode(DIRECTORY_SEPARATOR, $curentFile);
$mcap = array_slice($req, (array_search(end($file), $req) + 1));
if (count($mcap) < 3) {
return;
}
$route = array_slice($mcap, 0, 3);
list(self::$module, self::$controller, self::$action) = $route;
//如果使用剩余参数传参,则为索引数组;
self::$params = array_slice($mcap, 3);
}
}
?>
运行实例 »
点击 "运行实例" 按钮查看在线实例实例 -- 入口文件1 -- 这里使用依赖注入实现
<?php
include 'Autoloader.php';
Router::getRoute(__FILE__);
$model = new Model();
$view = new View();
$controller = new Router::$controller($model, $view);
if (is_null(Router::$module)) {
$controller->index();
} else {
$action = Router::$action;
if (method_exists($controller, Router::$action)) {
$controller->$action(...Router::$params);
} else {
die("未找到页面,请检查url...");
}
}
?>
运行实例 »
点击 "运行实例" 按钮查看在线实例实例 --- 这里使用“服务容器” 和 “静态代理”
<?php
include 'Autoloader.php';
Router::getRoute(__FILE__);
//服务容器
class Container {
protected $instance = [];
//保存到关联数组;
public function bind($alias, Closure $process) {
$this->instance[$alias] = $process;
}
//从数组中取出类的实例化过程;
public function make($alias, $params = []) {
return call_user_func_array($this->instance[$alias], []);
}
}
$contanier = new Container();
$contanier->bind('model', function () {
return new Model();
});
$contanier->bind('view', function () {
return new View();
});
class Facade {
protected static $contanier = null;
protected static $data = [];
public static function initialize(Container $contanier) {
static::$contanier = $contanier;
}
public static function getData(){
static::$data = static::$contanier->make('model')->getData();
}
public static function blogData(){
static::$data = static::$contanier->make('model')->blogData();
public static function showIdex(){
return static::$contanier->make('view')->showIdex(static::$data);
}
public static function showBlog(){
return static::$contanier->make('view')->showBlog(static::$data);
}
}
$controller = new Router::$controller();
if (is_null(Router::$module)) {
$controller->index($contanier);
} else {
$action = Router::$action;
if (method_exists($controller, Router::$action)) {
$controller->$action($contanier, ...Router::$params);
} else {
die("未找到页面,请检查url...");
}
}
?>
运行实例 »
点击 "运行实例" 按钮查看在线实例实例 --- 控制器 代码,“静态代理代码已注释”
<?php
// require 'Model.php';
// require 'View.php';
//控制器
class Controller_s {
//静态代理需要依赖注入的方法拿到容器
// public function __construct($container) {
// Face::initialize($container);
// }
//默认action: 请求index;
public function index(Container $contanier) {
// Face::getData();
// Face::showIdex();
$data = $contanier->make('model')->getData();
$contanier->make('view')->showIdex($data);
}
//请求blog的action
public function blog(Container $contanier) {
// Face::blogData();
// Face::showBlog();
$data = $contanier->make('model')->blogData();
$contanier->make('view')->showBlog($data);
}
//自定义方法,传参数
public function add($contanier, $name = 'Victor', $age = '30', $salary = 20000) {
echo __METHOD__
. ': 姓名: '
. $name
. ', 年龄: '
. $age
. ', 工资: '
. $salary;
}
}
// class Face extends Facade {
// //--
// }
?>
运行实例 »
点击 "运行实例" 按钮查看在线实例实例 -- Model代码
<?php
class Model {
public function getData() {
return 'Model中取到的index数据';
}
public function blogData() {
return 'Model中取到的blog数据';
}
public function getInfo($name, $age, $salary) {
return __METHOD__
. ': 姓名: '
. $name
. ', 年龄: '
. $age
. ', 工资: '
. $salary;
// return 'Model中取到的index数据';
}
}
?>
运行实例 »
点击 "运行实例" 按钮查看在线实例实例 --- View代码
<?php
class View {
public function showIdex($data) {
echo '在View中显示: ' . $data;
}
public function showBlog($data) {
echo '在View中显示: ' . $data;
}
public function showUserInfo($data) {
echo '在View中显示用户信息: ' . $data;
}
}
?>
运行实例 »
点击 "运行实例" 按钮查看在线实例总结:
1、学习了php路由机制、依赖注入、服务容器和门面类(静态代理),基本了解使用情况和原理;
2、这个“静态代理” 确实 应该叫 “门面类”,绕来绕去,就是为了控制器中的代码变得简单又简单,说白了就是为框架使用者方便,体验好,但实际上后面多了撑门面的类,还得把modle和view中的方法重构一次,很多的代码,其实远不如依赖注入直观简便。作为初学者,实在不知这样做编写效率和运行效率该怎么比较。
3、感觉可以把modle和view中的方法分别做成Trait插件,设为protected,然后让门面类全部引用过来,通过__callStatic()魔术方法应该可以访问到modle和view。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号