前言

下面准备审一下Yii、laravel、tp,但这些框架都是基于MVC模式的,所以先简单了解下MVC模式。

MVC是什么

MVC(Model-View-Controller)是软件工程的一种软件架构模式。

在MVC模式设计下,软件系统被分来三个模块:模型(Model)、视图(VIew)、控制器(Controller)。

  • Model(模型):是应用程序中用于处理应用程序数据逻辑的部分,通常负责与数据库直接进行 curd 的交互。

  • View(视图):是应用程序处理数据显示的部分,通过将处理好的数据进行渲染。

  • Controller(控制器):是应用程序中处理用户交互的部分,通常用于处理数据逻辑的分发,并相应的反送给视图和控制器。

简而言之View就是我们所看到的界面,Model就是View所显示界面的后端数据,而Controller就相当于是View和Model之间的桥梁

为什么使用MVC框架

在PHP中使用MVC框架,可以实现了分层、分类开发,实现了web的分离,使前端代码与后端分离,某一层的调整,不会对另一层的代码和逻辑造成影响,使用MVC开发框架更加方便程序的扩展,使开发的代码整体更加清晰

MVC框架

目录结构

  • app目录:应用目录(多模块)

    • 单模块:即一个主界面,其中包含ModelViewController
    • 多模块:有多个主界面,并都包含ModelViewController
  • config目录: 配置文件目录
  • Sentiment目录:核心文件目录
  • public目录: WEB目录(对外访问目录)

url访问控制器

先在app目录下写个控制器,这时通过public下的index.php直接访问控制器是访问不到的

现在就是需要对入口文件index.php进行配置,先获取下边三个路径,方便对mvc路径进行构造

<?php
define('APP_PATH',dirname(__DIR__));$script_name=$_SERVER['SCRIPT_NAME'];  // /public/index.php
$request_url=$_SERVER['REQUEST_URI'];  // /public/index.php/index/home/index?id=123&titile=456
$query_string=$_SERVER['QUERY_STRING']; // id=123&titile=456
?>

之后就是需要取出mvc中需要的部分,并通过$action调用对应的index方法

<?php
define('APP_PATH',dirname(__DIR__));$script_name = $_SERVER['SCRIPT_NAME'];  // /public/index.php
$request_url = $_SERVER['REQUEST_URI'];  // /public/index.php/index/home/index?id=123&titile=456
$query_string = $_SERVER['QUERY_STRING']; // id=123&titile=456// 需要 index/home/index
$url = str_replace($script_name,'',$request_url);  // /index/home/index?id=123&titile=456
$url = str_replace($query_string,'',$url);         // /index/home/index?
$url = ltrim($url,'/');                          // index/home/index?
$url = rtrim($url,'?');                          // index/home/index
$url = explode('/',$url);$model = $url[0];
$controller = $url[1];
$action = $url[2];$path = APP_PATH.'/app/'.$model.'/controller/'.$controller.'.php';
require_once $path;
$new = new $controller;
$new ->$action();
?>

结果:

之后可以优化一下mvc的赋值模式(if/else 避免因用户传参问题导致无法访问对应的index方法),但这种方式若想调用不同的方法 每次都需要修改else中的值,因此可以通过config配置文件 进行修改

<?php
define('APP_PATH',dirname(__DIR__));$script_name = $_SERVER['SCRIPT_NAME'];  // /public/index.php
$request_url = $_SERVER['REQUEST_URI'];  // /public/index.php/index/home/index?id=123&titile=456
$query_string = $_SERVER['QUERY_STRING']; // id=123&titile=456// 需要 index/home/index
$url = str_replace($script_name,'',$request_url);  // /index/home/index?id=123&titile=456
$url = str_replace($query_string,'',$url);         // /index/home/index?
$url = ltrim($url,'/');                          // index/home/index?
$url = rtrim($url,'?');                          // index/home/index
$url = explode('/',$url);if(count($url) >= 3){$model = $url[0];$controller = $url[1];$action = $url[2];
} else {$model = 'index';$controller = 'home';$action = 'index';
}$path = APP_PATH.'/app/'.$model.'/controller/'.$controller.'.php';
require_once $path;
$new = new $controller;
$new ->$action();
?>

/config/app.php

<?phpreturn['default_model'=>'index','default_controller'=>'Home','default_action'=>'index'
];

之后将else部分替换成

 else {$config=require_once APP_PATH.'/config/app.php';$model = $config['default_model'];$controller = $config['default_controller'];$action = $config['default_action'];
}

此时访问/public/index.php/,即可默认调用/app/index/Home/的index方法

但其实不需要很多入口文件,所以这里就把原本的index.php入口文件构建到核心文件Sentiment中,除此之外如果count >=3时,若访问不存在的控制器例如/index/index/index,他还是会报错,所以通过下边的三个if语句,再次进行优化

/Sentient/Sentiment.php

<?php
class Sentiment
{public static function init(){$script_name = $_SERVER['SCRIPT_NAME'];  // /public/index.php$request_url = $_SERVER['REQUEST_URI'];  // /public/index.php/index/home/index?id=123&titile=456$query_string = $_SERVER['QUERY_STRING']; // id=123&titile=456// 需要 index/home/index$url = str_replace($script_name,'',$request_url);  // /index/home/index?id=123&titile=456$url = str_replace($query_string,'',$url);         // /index/home/index?$url = ltrim($url,'/');                          // index/home/index?$url = rtrim($url,'?');                          // index/home/index$url = explode('/',$url);if(count($url) >= 3){$model = $url[0];$controller = $url[1];$action = $url[2];} else {$config=require_once APP_PATH.'/config/app.php';$model = $config['default_model'];$controller = $config['default_controller'];$action = $config['default_action'];}//判断应用模块if(!is_dir(APP_PATH.'/app/'.$model)){exit("应用模块<".$model.">不存在!");}$path = APP_PATH.'/app/'.$model.'/controller/'.$controller.'.php';//判断控制器if(!file_exists($path)){exit("控制器<".$controller.">不存在!");}require_once $path;$new = new $controller;//判断方法if(!method_exists($new,$action)){exit("方法< ".$action ." >不存在");}return ['new'=> $new,'action'=>$action];}
}

/Sentiment/App.php

<?php
define('APP_PATH',dirname(__DIR__));
require_once APP_PATH.'/Sentiment/Sentiment.php';$init = Sentiment::init();
$new =$init['new'];
$action=$init['action'];
$new->$action();

/public/index.php

<?php
define('APP_PATH',dirname(__DIR__));
require_once APP_PATH.'/Sentiment/App.php';
?>

此时就可以通过index.php,访问到核心文件的入口了,访问不存在的应用模块、控制器、方法时会返回提示信息,如下图访问方法ccc时,则会输出提示信息

访问视图层、页面跳转、函数助手

访问视图

/app/index/view/下建一个home文件,再在其中建一个index.php

<?php
echo "this is view";
?>

此时只需要修改Home.php的index方法,便可直接访问到视图层

<?php
class Home
{public function index(){require_once APP_PATH.'/app/index/view/home/index.php';}
}


这里可以做一下优化,把require_once的内容写到核心文件Sentiment中

/Sentiment/Sentiment.php

<?php
class Sentiment
{public static function init(){$script_name = $_SERVER['SCRIPT_NAME'];  // /public/index.php$request_url = $_SERVER['REQUEST_URI'];  // /public/index.php/index/home/index?id=123&titile=456$query_string = $_SERVER['QUERY_STRING']; // id=123&titile=456// 需要 index/home/index$url = str_replace($script_name,'',$request_url);  // /index/home/index?id=123&titile=456$url = str_replace($query_string,'',$url);         // /index/home/index?$url = ltrim($url,'/');                          // index/home/index?$url = rtrim($url,'?');                          // index/home/index$url = explode('/',$url);if(count($url) >= 3){$model = $url[0];$controller = $url[1];$action = $url[2];} else {$config=require_once APP_PATH.'/config/app.php';$model = $config['default_model'];$controller = $config['default_controller'];$action = $config['default_action'];}define('MODULE',$model);                //view的module路径//判断应用模块if(!is_dir(APP_PATH.'/app/'.$model)){exit("应用模块<".$model.">不存在!");}$path = APP_PATH.'/app/'.$model.'/controller/'.$controller.'.php';//判断控制器if(!file_exists($path)){exit("控制器<".$controller.">不存在!");}require_once $path;$new = new $controller;//判断方法if(!method_exists($new,$action)){exit("方法< ".$action ." >不存在");}return ['new'=> $new,'action'=>$action];}public static function view($path,$data){$path= APP_PATH.'/app/'.MODULE.'/view/'.$path.'.php';require_once $path;}
}

较之前多出的部分

 define('MODULE',$model);                //view的module路径public static function view($path,$data){$path= APP_PATH.'/app/'.MODULE.'/view/'.$path.'.php';require_once $path;}

/app/index/controller/Home.php

直接调用Sentiment的view方法,并传参path,和data

<?phpclass Home
{public function index(){Sentiment::view('home/index','456');}
}

/app/index/view/home/index.php

两种调用$data值得方法选一个即可

<?= $data ?>
<? echo $data;?>

此时在访问就是我们传入的456值

页面跳转

先创建个跳转文件/Sentiment/Load.php

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Document</title>
</head>
<body><h1><?=$msg?></h1><h3>页面自动跳转,等待 <b id="msg">3</b>秒,<a href="javascript:li()">跳转</a></h3><script>var msg = document.getElementById("msg");var i = 3;setInterval(function(){i--;msg.innerHTML = i;if(i<=0){window.location.href= "../<?= $path?>";}},1000);function li(){window.location.href = "../<?= $path ?>";}</script>
</body></html>

/Sentiment/Sentiment.php,创建load方法

public static function load($path,$msg){$url=APP_PATH.'/Sentiment/Load.php';require_once $url;
}

/app/index/controller/Home.php,通过abc方法跳转到index方法调用view

<?phpclass Home
{public function index(){Sentiment::view('home/index','456');}public function abc(){Sentiment::load('home/index',"Sentiment");}
}

结果

三秒后自动跳转index

函数助手

Sentiment/Common.php,将之前写的view、load函数写到其中

<?php
function dump($data){echo "<pre>";print_r($data);echo "</pre>";
}function view($path,$data){Sentiment::view($path,$data);
}function load($path,$msg){Sentiment::load($path,$msg);
}

在/Sentiment/App.php,进行文件包含

require_once APP_PATH.'/Sentiment/Common.php';

这时/app/index/controller/Home.php,就不需要通过Sentiment::view()这种方式调用了,而是直接view();即可

除此外dump方法便于输出数组,当index方法中,是数组时调用dump

<?phpclass Home
{public function index(){$data=['Sentiment'=>1,'Tana'=>2];dump($data);}public function abc(){load('home/index',"Sentiment");}
}

结果

其实整个运行的流程就是:/public/index.php—>/Sentiment/App.php(在Sentiment.php获取控制器和方法值)—>/app/index/controller/Home.php(由于App.php包含了Common.php,所以就不用通过::调用方法)

PHP MVC框架初探相关推荐

  1. mvc的宿舍管理系统源码 基于jsp_[源码和文档分享]基于JSP的MVC框架实现的图书推荐系统展示平台网站...

    推荐系统是目前互联网中最常见的一种智能产品形式.由于网络中信息量的快速增长以及图书出版行业出版量的攀升,人们需要一种办法,来解决信息过载的问题.此外,用户访问网络是为了获取信息,但并不是所有的访问都有 ...

  2. php mvc实例下载,php实现简单的MVC框架实例

    本文实例讲述了php实现简单的MVC框架.分享给大家供大家参考.具体如下: 在开始之前需要知道的知识 1.php基础知识 2.单一入口, 不知道的可以看看这里 具备以上两点, 那我们就可以开始啦. 哈 ...

  3. Scott的ASP.net MVC框架系列文章之四:处理表单数据(2)

    前几周我发表了一系列文章介绍我们正在研究的ASP.NET MVC框架.ASP.NET MVC框架为你提供了一种新的开发Web应用程序的途径,这种途径可以让应用程序变得更加层次清晰,而且更加有利于对代码 ...

  4. Spring MVC框架有哪些优点

    Spring MVC是Spring提供的一个实现了Web MVC设计模式的轻量级Web框架.它与Struts2框架一样,都属于MVC框架,但其使用和性能等方面比Struts2更加优异. Spring ...

  5. koa-grace:一个基于koa的node多应用MVC框架

    春节期间没回家留在北京写了一个基于koa的node MVC框架:koa-grace ,大家有兴趣可以star & fork下,谢谢支持啦!! 项目地址: https://github.com/ ...

  6. Java Web学习总结(30)——Service层在MVC框架中的意义和职责

    mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层设计, ...

  7. Spring MVC 框架搭建及详解

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...

  8. Java MVC框架性能比较 jsp、struts1、struts2、springmvc3 (转帖)

    为什么80%的码农都做不了架构师?>>>    Java MVC框架性能比较 jsp.struts1.struts2.springmvc3 现在各种MVC框架很多,各框架的优缺点网络 ...

  9. Asp.Net MVC 自定义的MVC框架(非EF操作数据库)

    一些废话:在北京辞职回家不知不觉中已经半年多了,这半年中有过很多的彷徨,困惑,还有些小小难受.半年时间算是我人生以来遇到过的最困苦的时候.理想的工作跟我擦肩而过,驾照也没有考过,年后这一改革...,毕 ...

最新文章

  1. 2019.2.7 区块链论文翻译
  2. 4028: [HEOI2015]公约数数列
  3. TS基础2(泛型、枚举、元组)-学习笔记
  4. git 2.30.1最新版本的使用
  5. java递增_java-8 – 如何按组递增
  6. 力扣40. 组合总和 II(JavaScript)
  7. python代码转换为pytorch_python基础教程Pytorch之Tensor和Numpy之间的转换的实现方法...
  8. [转]Java集合类: Set、List、Map、Queue使用场景梳理
  9. JavaScript的Date类的函数特殊处理导致的问题
  10. Sharepoint 2010 对话框框架
  11. Atitit 算法原理与导论 目录 1. Attilax总结的有用算法 按用途分类 1 1.1. 排序算法 字符串匹配(String Matching) 1 1.2. 加密算法 编码算法 序列
  12. 系统分析师论文评分标准
  13. AD域管理员账号下发
  14. 服务器cache文件夹里的东西可以删除吗,MSOCache文件夹可以删除吗?如何清理C盘空间?...
  15. 无线信道仿真 matlab,基于Matlab的无线信道仿真.doc
  16. 请教苹果虚拟机自动配置序列号ID脚本
  17. vue日历排班组件_vue之手把手教你写日历组件
  18. 沟通失败是怎样造成的
  19. 1-4 python爬取笔趣阁小说(附带完整代码)
  20. 红米 k30 pro 刷入欧版和小米钱包/商店

热门文章

  1. lnmp一键部署脚本
  2. 从零学习Fluter(八):Flutter的四种运行模式--Debug、Release、Profile和test以及命名规范...
  3. ESP32自动更新气象站
  4. 搭建私有云:owncloud(用Docker构建owncloud私有云盘)
  5. mybatis的JavaType和ofType区别
  6. [uni-app]聊天App实例
  7. 白盒测试(单元测试JUnit使用断言assertThat中startsWith、endsWith方法)
  8. Windows中查看8080端口的占用情况并关闭相关进程
  9. linux grep 和 find 命令
  10. Liunx学习笔记 - 07 - 02 正则表达式与文件格式化处理