MVC介绍
MVC(Model View Controller)是软件工程中的一种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
M:Model,模型
完成具体的业务操作,如:查询数据库,封装对象
V:view视图。JSP、HTML等来进行数据展示
C:Controller控制器。 Servlet
获取View的请求
调用模型将数据交给视图进行展示
MVC结构
目录
|——app: 应用目录(多模块)
|——单模块: 即一个主界面,其中包含Model、View、Controller
|——多模块: 即一个主界面,其中包含Model、View、Controller
|——config: 配置文件目录
|——pro: 核心目录文件
|——public: WEB目录文件
url访问控制器
先在public 下创建index.php
然后访问
http://127.0.0.1:3678/public/index.php/
可以访问得到
如果访问 app/index.php 可以直接修改url地址 , 所以我们切换目录文件
在网站根目录下添加 public 目录
访问 /app/ 就会报错了
在 app 下写个控制器
然后访问控制器里面的方法
http://127.0.0.1:3678/index.php/index/home/index?id=123&titile=456
我们可以找到这些东西
[SCRIPT_NAME] => /index.php
[REQUEST_URI] => /index.php/index/home/index?id=123&titile=456
[QUERY_STRING] => id=123&titile=456
$script_name=$_SERVER['SCRIPT_NAME'];
$request_url=$_SERVER['REQUEST_URI'];
$query_string=$_SERVER['QUERY_STRING'];
然后提取我们想要的部分 /index/home/index?
...
$url = str_replace($script_name, '' ,$request_url);
$url = str_replace($query_string,'',$url);
echo $url;
然后去除前面的 / 和后面的 ?
...
$url = str_replace($script_name, '' ,$request_url);
$url = str_replace($query_string,'',$url);
$url = ltrim($url,'/');
$url = rtrim($url,'?');
echo $url;
然后变成数组的形式
$url = explode('/',$url);
print_r($url);
接着各区所需
$model = $url[0];
$controller = $url[1];
$action = $url[2];
先定义一个路径
define("APP_PATH",dirname(__DIR__));
...
$path = APP_PATH.'/app/'.$model.'/controller/'.$controller.'.php';
echo $path;
...
实例化控制器 访问方法
...
define("APP_PATH",dirname(__DIR__));
$path = APP_PATH.'/app/'.$model.'/controller/'.$controller.'.php';
require_once $path;
$new = new $controller;
$new ->$action();
...
<?php
define("APP_PATH",dirname(__DIR__));
$script_name=$_SERVER['SCRIPT_NAME'];
$request_url=$_SERVER['REQUEST_URI'];
$query_string=$_SERVER['QUERY_STRING'];
$url = str_replace($script_name, '' ,$request_url);
$url = str_replace($query_string,'',$url);
$url = ltrim($url,'/');
$url = rtrim($url,'?');
$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();
然后优化一下目录访问路径
/public/index.php
...
if(count($url) >= 3){
$model = $url[0];
$controller = $url[1];
$action = $url[2];
} else {
$model = 'index';
$controller = 'Home';
$action = 'index';
}
...
/config/app.php
<?php
return[
'default_module' => 'index',
'default_controller' => 'Home',
'defalut_action' => 'index',
];
然后替换代码
/public/index.php
...
else{
$config = require_once APP_PATH . '/config/app.php';
$model = $config['default_model'];
$controller = $config['default_controller'];
$action = $config['default_action'];
}
然后访问http://127.0.0.1:3678/index.php/
但其实不需要很多入口文件,所以这里就把原本的index.php 入口文件构建到核心文件Pro 中,除此之外如果count >=3时,若访问不存在的控制器例如/index/index/index,他还是会报错,所以通过下边的三个if语句,再次进行优化
/Pro/Pro.php
<?php
class Pro
{
public static function init()
{
$script_name = $_SERVER['SCRIPT_NAME'];
$request_url = $_SERVER['REQUEST_URI'];
$query_string = $_SERVER['QUERY_STRING'];
$url = str_replace($script_name,'',$request_url);
$url = str_replace($query_string,'',$url);
$url = ltrim($url,'/');
$url = rtrim($url,'?');
$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];
}
}
/Pro/App.php
<?php
define('APP_PATH',dirname(__DIR__));
require_once APP_PATH.'/Pro/Pro.php';
$init = Pro::init();
$new = $init['new'];
$action = $init['action'];
$new->$action();
/public/index.php
<?php
define('APP_PATH',dirname(__DIR__));
require_once APP_PATH.'/Pro/App.php';
?>
此时就可以通过 index.php ,访问到核心文件的入口了,访问不存在的应用模块、控制器、方法时会返回提示信息,如下图访问方法 abc 时,则会输出提示信息
http://127.0.0.1:3678/index.php/index/home/abc
访问视图层
/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';
}
然后把核心的代码写入到核心文件里
/Pro/Pro.php
<?php
class Pro
{
public static function init()
{
$script_name = $_SERVER['SCRIPT_NAME'];
$request_url = $_SERVER['REQUEST_URI'];
$query_string = $_SERVER['QUERY_STRING'];
$url = str_replace($script_name,'',$request_url);
$url = str_replace($query_string,'',$url);
$url = ltrim($url,'/');
$url = rtrim($url,'?');
$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('MODEL',$model);
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/'.MODEL.'/view/'.$path.'.php';
require_once $path;
}
}
/app/index/controller/Home.php
<?php
class Home{
public function index(){
Pro::view('home/index','test_test');
}
}
/app/index/view/home/index.php
<?= $data ?>
此时在访问就是我们传入的 test_test 值
页面跳转
先创建个跳转文件 /Pro/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>
Pro/Pro.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
<?php
class Home{
public function index(){
Sentiment::view('home/index','test_test');
}
public function abc(){
Sentiment::load('home/index',"Muz1");
}
}
访问 /index.php/index/home/abc
函数助手
Pro/Common.php ,将之前写的view、load函数写到其中
<?php
function dump($data){
echo "<pre>";
print_r($data);
echo "</pre>";
}
function view($path,$data){
Pro::view($path,$data);
}
function load($path,$msg){
Pro::load($path,$msg);
}
在/Pro/App.php ,进行文件包含
require_once APP_PATH.'/Pro/Common.php';
这时/app/index/controller/Home.php ,就不需要通过 Pro::view() 这种方式调用了,而是直接 view(); 即可
除此外dump方法便于输出数组,当index方法中,是数组时调用dump
<?php
class Home
{
public function index(){
$data = ['Muz1' => 1,'test' => 2];
dump($data);
}
public function abc(){
Pro::load('home/index','Muz1');
}
}
结果
运行流程是
/public/index.php -->
require_once APP_PATH.'/Pro/App.php';
/Pro/App.php -->
require_once APP_PATH.'/Pro/Pro.php';
在Pro.php获取控制器和方法值
/app/index/controller/Home.php(由于App.php包含了Common.php,所以就不用通过::调用方法)
|