PHP仿tp实现mvc框架基本设计思路与实现方法分析


Posted in PHP onMay 23, 2018

本文实例讲述了PHP仿tp实现mvc框架基本设计思路与实现方法。分享给大家供大家参考,具体如下:

仿tp mvc基本设计与简单实现

一:文件加载常识

变量 常量 函数 类
文件加载的函数或者使用命名空间:require();   require_once();   include();   include_once();
常量:define("DEFINE","");   const constant = "value";
函数:function fun(){}  // global 使用全局变量    局部变量不被外部调用。
类:

<?php
class A{
  public $a = 10;
  public function aa(){  // 不能使用一个a是因为,new A 之后 方法a会被自动执行,所以方法名不可以和类名冲突。
    echo $this->a; // 输出属性.
  }
  public function __construct(){ // 构造方法,实例化后自动执行,
    echo $this->bb(); // 调用方法。
  }
  public function bb(){
    echo "我是bb";
  }
}
$a = new A;
$a->aa();
class B extends A{ // 继承 A ,类A是类B的父级。继承public的,
}
$b = new B;
$b->aa(); // 可以输出类A里面的属性。

工厂模式参阅:https://3water.com/article/140658.htm

//-----------------------------工厂模式-------------------------//
class A{
  public $class;   // public $class = $_GET['c']; //类名
  public $method; // public $method = $_GET['m']; //方法
  public function __construct($class,$method){
    // 或者通过 $_SERVER['PATH_INFO']; 转换得到类名或者方法名(下面讲解)。
    $this->class = ucfirst(strtolower($class)).'Controller'; //对类名进行安全处理,并加上控制器后缀
    $this->method = strtolower($method);   //对方法名进行安全处理
    $this->work($this->class,$this->method);
  }
  public function work($class,$method){
    // 把文件命名成 (类名.class.php的形式),就可以通过类名找到文件。
    //include '文件名(文件在别的地方)';    #例如 include './index.php'; 引入文件然后实例化类。
    $c = new $class;  //实例化类
    $c->$method();  //访问类的方法
  }
}

至此我们可以通过url的 $_GET 参数来解决

例如:http://mvc.com/index.php?h=home&v=Index&c=index.html

h为前后台,v为控制器,c为模板。

$v = $_GET['v'];
$c = rtrim($_GET['c'],".html");
new A($v,$c); // 根据继承关系再次加载文件。
// extract($arr);  //extract 的作用:从数组中将变量导入到当前的符号表,键做变量,值做值!
// compact(); // — 建立一个数组,包括变量名和它们的值
// assign display 实现参阅:https://3water.com/article/140661.htm
class Controller{
  public $array;
  public $key;
  public $val;
  public function assign($key,$val){
    if(array($val)){
      $this->array["$key"] = $val;
    }else{
      $this->array["$key"] = compact($val);
    }
  }
  public function display($tpl = ''){ // 模板为空自动加载。
    $this->assign($this->key,$this->val);
    extract($this->array);
    // 如果模板为空就在这里根据get参数添加或者通过 $_SERVER['PATH_INFO']; 转换得到。(下面讲解)
    if(file_exists($tpl)){ //模板存在就加载文件。
      include $tpl;
    }
  }
}
//继承总model。这个model名字和控制器model的名字是一样的。继承方法同Controller,总model必须需要加上一个return。数据处理的indexmodel可以加return,也可以不加。
class IndexModel extends Model{
  public function index(){
    // 数据处理。
    // 需要返回数据就加上return。
  }
}
class IndexController extends Controller{ // 继承
  public function index(){
    $m = Model("index");
    echo '实例化后的index方法<br>';
    $this->assign('m',$m); // 分配数据。
    $this->display('index.html'); // 模板
  }
}

mvc虽然实现但是不够人性化,因为每次都要加上get参数,变得很冗长,解决的关键在于$_SERVER['PATH_INFO'];

用这个替换掉h m v三个参数。

1. 当输入url为:http://mvc.com/index.php/home/index/index.html
    这种情况下  index.php 斜线后面的apache会自动认为是一个路径。
    $_SERVER['PATH_INFO'] =  /home/index/index.html
    第1个斜线 /home        前后台
    第2个斜线 /index        控制器
    第3个斜线 /index.html  模板文件
    如果后面加有参数例如:?a=18&b=38   他不会被加到$_SERVER['PATH_INFO']里面。$_POST 或者 $_GET 也不会加入$_SERVER['PATH_INFO']里面的内容,这样就可以让控制参数和数据的参数互不冲突。

2. U 方法的实现。重新改写$_SERVER['PATH_INFO'] 参数,改变为一个数据。array( 'home', 'Index', 'index');

每次进入入口文件index.php都把他的PHP_INFO参数转换为数组,在控制器或者其他的地方只要调用这个参数就行了。

// 这里如果做了大小写的转换,总控制器里面就不用了。
function bca(){
  $arr = explode('/',ltrim($_SERVER['PATH_INFO'],'/'));
  if(count($arr) == 3){
    $arr[0] = strtolower($arr[0]);
    $arr[1] = ucfirst(strtolower($arr[1]));
    // 判断后缀是不是 .html
    if(substr($arr[2],-5,strlen($arr[2])) == '.html'){
      $a = explode('.',$arr['2']);
      $arr[2] = strtolower($a[0]);
    }else{
      $arr[2] = strtolower($arr[2]);
    }
    $_SERVER['PATH_INFO'] = $arr;
  }
}
// url方法做控制器或前后台的跳转。第三个参数是输出还是return。默认是直接输出。
function U($string = '',$method = '',$bool = true){ // true 是直接输出或者返回,
  // 获取系统变量。
  $path_info = $_SERVER['PATH_INFO'];
  $script_name = $_SERVER['SCRIPT_NAME'];
  // 判断中间有没有 / 以确定参数个数。
  if(strpos($string,'/')){
    $arr = explode('/',$string);
    if(count($arr) == 2){  // 两个参数的情况。
      $arr[0] = ucfirst(strtolower($arr[0]));
      $arr[1] = strtolower($arr[1]);
      $url = "/{$path_info[0]}/{$arr[0]}/{$arr[1]}.html";
    }else if(count($arr) == 3){ // 三个参数的情况。
      $arr[0] = strtolower($arr[0]);
      $arr[1] = ucfirst(strtolower($arr[1]));
      $arr[2] = strtolower($arr[2]);
      $url = "/{$arr[0]}/{$arr[1]}/{$arr[2]}.html";
    }
  }else{
    $arr = strtolower($string); // 一个参数的情况。
    $url = "/{$path_info[0]}/{$path_info[1]}/{$arr}.html";
  }
  // url 路径的拼接。
  if($method != ''){
    $u = $script_name.$url.'?'.$method;
    if($bool == true){     echo $u;    }else{     return $u;   }
  }else{
    $u = $script_name.$url;
    if($bool == true){     echo $u;    }else{     return $u;   }
  }
}

3. url重写,去掉 index.php

打开apache配置文件重写模块,LoadModule rewrite_module modules/mod_rewrite.so

根下加入的改写文件  .htaccess

内容:

<IfModule mod_rewrite.c>
 Options +FollowSymlinks
 RewriteEngine On
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

在浏览器输入url:http://mvc.com/home/index/index.html?a=19b=38
    [REDIRECT_STATUS] => 200  重写状态ok。

发现 $_SERVER['REDIRECT_URL'];$_SERVER['PATH_INFO']; 参数相同。所以参数后面就可以去掉index.php这安全的问题。

4. 模板替换(思路)

我们会发现有一个我们书写的模板,里面有 {$arr}  <include file="" /> 等,我们把模板文件读取后通过正则还有字符串把他转换成正常的php文件。对文件名加密后放到替换后的文件夹下,每次url访问的时候查看是否有缓存文件,判断最后修改时间等验证,

5. 数据缓存(思路)

json_encode() json_decode() file_get_contents() file_put_contents(); unserialize();  serialize(); 等存文文件里面或者memcache redis 等存储。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
把PHP安装为Apache DSO
Oct 09 PHP
Discuz! Passport 通行证整合
Mar 27 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
Apr 26 PHP
PHP SPL使用方法和他的威力
Nov 12 PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
Mar 08 PHP
Yii使用find findAll查找出指定字段的实现方法
Sep 05 PHP
php解析http获取的json字符串变量总是空白null
Mar 02 PHP
php商品对比功能代码分享
Sep 24 PHP
腾讯CMEM的PHP扩展编译安装方法
Sep 25 PHP
PHP简单的MVC框架实现方法
Dec 01 PHP
php curl中gzip的压缩性能测试实例分析
Nov 08 PHP
PHP5.5基于mysqli连接MySQL数据库和读取数据操作实例详解
Feb 16 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
May 23 #PHP
PHP工厂模式简单实现方法示例
May 23 #PHP
PHP递归遍历文件夹去除注释并压缩php源代码的方法示例
May 23 #PHP
PHP实现将多个文件压缩成zip格式并下载到本地的方法示例
May 23 #PHP
PHP实现的mysql读写分离操作示例
May 22 #PHP
PHP基于pdo的数据库操作类【可支持mysql、sqlserver及oracle】
May 21 #PHP
PHP+MariaDB数据库操作基本技巧备忘总结
May 21 #PHP
You might like
PHP学习 变量使用总结
2011/03/24 PHP
那些年一起学习的PHP(三)
2012/03/22 PHP
Laravel学习教程之从入口到输出过程详解
2017/08/27 PHP
一个简单的jquery的多选下拉框(自写)
2014/05/05 Javascript
jQuery分组选择器用法实例
2014/12/23 Javascript
纯css实现窗户玻璃雨滴逼真效果
2015/08/23 Javascript
微信小程序商品到详情的实现
2017/06/27 Javascript
layui中layer前端组件实现图片显示功能的方法分析
2017/10/13 Javascript
ES6的解构赋值实例详解
2019/05/06 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
html+vue.js 实现漂亮分页功能可兼容IE
2020/11/07 Javascript
[03:54]DOTA2英雄梦之声_第06期_昆卡
2014/06/23 DOTA
python和C语言混合编程实例
2014/06/04 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
2017/11/01 Python
python sort、sort_index方法代码实例
2019/03/28 Python
Python3.8对可迭代解包的改进及用法详解
2019/10/15 Python
Python socket模块方法实现详解
2019/11/05 Python
keras 特征图可视化实例(中间层)
2020/01/24 Python
html5响应式开发自动计算fontSize的方法
2020/01/13 HTML / CSS
美国嘻哈首饰购物网站:Hip Hop Bling
2016/12/30 全球购物
Diamondback自行车:拥有你的冒险
2019/04/22 全球购物
白俄罗斯女装和针织品网上商店:Presli.by
2019/10/13 全球购物
公司市场部岗位职责
2013/12/02 职场文书
秘书英文求职信范文
2014/01/31 职场文书
会议邀请书范文
2014/02/02 职场文书
公司总经理工作职责管理办法
2014/02/28 职场文书
周年庆促销方案
2014/03/15 职场文书
农村党支部书记四风问题个人对照检查材料
2014/09/21 职场文书
医生见习报告范文
2014/11/03 职场文书
民间借贷纠纷答辩状
2015/08/03 职场文书
祝酒词范文
2015/08/12 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书
MYSQL 无法识别中文的永久解决方法
2021/06/03 MySQL
css布局巧妙技巧之css三角示例的运用
2022/03/16 HTML / CSS
前端JS获取URL参数的4种方法总结
2022/04/05 Javascript