php原生代码自己做mvc框架,做一个自己的MVC框架[php]

外包的活干多了,总有一些小项目,这些小项目甚至不需要考虑安全。这时候用框架显得浪费。自己手写原生代码又有些不太习惯(框架用多了,有时候连基本的都忘了,不能忘本啊。。。)

许久不更的博客。反正也没多少人看,哈~就当给自己一个马克,也希望能给一些刚踏入程序猿大军的新手们做到一个了解MVC抛砖引玉的小作用吧。

唠唠叨叨一些废话,开始说真的。

———-我是分割线—————–

1.我对MVC的理解

再唠叨一遍MVC三个字母的含义吧

M:model->模型。一般是操作数据的地方

V:view->视图。用户肉眼直接看到的界面

C:controller->控制器。控制整个应用的作用(好难全面解释,比如之所以点保存能够保存信息而不是删掉信息,这就是控制器的作用)

所以,MVC结构在项目开发中的绝大部分作用就是从控制器(C)作为切入点[和个人习惯有关系,但是前提要架构好整体项目],调用模型接口(M)进行数据操作,并且展示在视图(V)上,以视觉的方式直观的反映给用户。

2.预设框架的基本结构

因为比较熟悉CI框架,也用过TP框架所以基本结构如下:

1).一个框架要有一个入口文件

2).框架和URL基本调用方式为

http://基本网址/入口文件/控制器的文件夹/控制器/方法?参数名=参数值&参数名=参数值

3.文件夹结构

这里列出基本的文件及文件夹的结构

-info..........................框架文件夹

-config....................配置文件夹

database.php...........数据库配置文件

-controller................用户控制器文件夹

-test..................用户控制器文件夹

welcome.php........用户控制器文件

-core......................本框架的一些核心文件

Info_Controller.php....框架的核心控制器

Info_Model.php.........框架核心模型

route.php..............框架的路由规则

-models....................用户模型文件夹

user_model.php.........用户模型文件

-views.....................用户视图文件夹

welcome.html...........用户视图文件

index.php..................单入口文件

4.开始~

0).但入口文件设置基本信息

1).路由 从URL获取所有的目标信息

URL:

localhost/info/index.php/test/welcome/hello.php?getKey=getValue

从上述URL可以提取到,

我们要调用welcome控制器下的hello方法,并且以GET方式传入了参数名:getKey,参数值:getValue这样一对k/v;

熟悉 $_SERVER 的应该知道这样一个变量 :$_SERVER[‘PATH_INFO’]。

(可以通过 var_dump($_SERVER)查看,如果没有,则说明服务器没有打开path_info,本文默认打开)

该变量可以简单地理解为记录了从脚本文件(即单入口文件)到传参开始的完整路径

即’/test/welcome/hello.php’部分,所以我们要利用该变量分割出文件夹、控制器以及方法。直接上代码比较明显

<?php #info/core/index.php #获取controller和function $pathInfo = $_SERVER['PATH_INFO']; $pathArr = explode('/', $pathInfo);#分割文件夹、控制器和方法 array_shift($pathArr);#删除第一个空元素,因为PATH_INFO以'/'开始 $length = sizeof($pathArr);#获取长度用来分离出控制器和方法 #获取路径 $root = SERVER_ROOT . CONTROLLER_ROOT; for ($i=0; $i < $length-2; $i++) { $root .= '/'.$pathArr[$i]; } #判断类文件及类是否存在 #命名规则为: #控制器文件为小写字母+'.php':welcome.php #控制器类名为首字母大写+'_Controller':Welcome_Controller $class = $pathArr[$length-2];#$pathArr的最后元素为方法名 $className = ucfirst($class) . '_Controller'; $classFile = $root . '/' . $class . '.php'; unset($class);#用完释放,防止变量污染 if (!file_exists($classFile)) { exit('404'); }else{ include $classFile;#文件存在,引入 if (class_exists($className)) { $class = new $className();#类存在,实例化 }else{ exit('class not exist');#类不存在,报错 } } #获取并调用function $functionStr = $pathArr[$length-1]; #为了做到伪静态,有时候方法后面我们加上'.html'或者'.php' $functionArr = explode('.', $functionStr); if (sizeof($functionArr)==2) { $function = $functionArr[0]; $scriptType = $functionArr[1]; }else{ $function = $functionArr[0]; $scriptType = 'undefined'; } #获得类和方法之后调用 $class->$function();

因为我是在完成这个框架之后写的该文,所以一定可用。

还是给出测试吧。

在controller下新建一个文件 hello.php

测试结果如图:

0818b9ca8b590ca3270a3433284dd417.png

2)控制器加载视图

前面已经做了URL到控制器和方法的路由,下面来做控制器加载视图。

因为PHP是一种可嵌入到HTML的脚本,所以我们可以直接在方法中include一个HTML,(好直白。。。)。同理,方法中所有在include之前声明的变量都可以直接用,但这也是一个弊端,即所有的变量都可以在HTML中使用。所以我们将include封装成一个方法,任何将要显示在HTML页面的变量都以参数的方式传给该方法。

考虑到该方法可能会被多次调用,所以封装为核心类的方法,这样每次新建一个方法只要继承核心类就可以调用。即在info_Controller.php中声明一个loadView的方法,之后controller文件夹下所有的类都extends Info_Controller即可:

#用户自定义类 info/controller/test/welcome.php

class Welcome_Controller extends Info_Controller{

public function hello(){

$data['key'] = 'value';

$this->loadView('welcome.html',$data);

}

}

}

helloworld

测试结果:

0818b9ca8b590ca3270a3433284dd417.png

3)控制器调用模型

模型层我们主要是用来进行数据库操作。首先我们要连接数据库。

连接数据库的信息,一般我们都放在单独的配置文件,连接的时候直接引入该文件即可。

#/info/config/database.php

$_DATABASE['DBdriver'] = 'mysql';

$_DATABASE['host'] = 'localhost';

$_DATABASE['port'] = '3306';

$_DATABASE['username'] = 'root';

$_DATABASE['password'] = 'root';

$_DATABASE['database'] = 'bbs';

同2),我们肯能要多次进行数据库操作,所以每次都去connect数据库太繁琐,这里我们把连接数据库的操作写在核心model文件:info_model.php的构造函数中,这样之后我们每次新建一个模型的时候直接继承核心model类即可。

#info/core/Info_Model.php

#这里我们使用PDO进行连接

require_once(SERVER_ROOT . "/config/database.php");

class Info_Model{

function __construct(){

#链接数据库

global $_DATABASE;#方法外的变量通过global引入

$driver = $_DATABASE['DBdriver'];

$host = $_DATABASE['host'];

$port = $_DATABASE['port'];

$username = $_DATABASE['username'];

$password = $_DATABASE['password'];

$database = $_DATABASE['database'];

$this->db = new PDO("$driver:host=$host;dbname=$database;charset=utf8mb4",$username,$password);

$this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);#默认返回关联数组

$this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); #禁用prepared statements的仿真效果

}

}

每个model文件中的类需要实例化之后才能使用。所以我们可以像2)中加载视图一样,在核心控制器中封装一个加载模型的函数

#/info/core/Info_Controller.php

class Info_Controller{

#加载控制器

public function loadView($view,$data=NULL){

$data = $data;

require_once(SERVER_ROOT . "/views/$view");

}

#加载模型

public function loadModel($model,$alias=NULL){

$modelFile = SERVER_ROOT . "/models/$model" . '.php';

if (!file_exists($modelFile)) {

exit('404');

}else{

require_once($modelFile);

#参考CI,可以给调用的模型一个别名

if ($alias) {

$this->$model=$this->$alias = new $model();

}else{

$this->$model = new $model();

}

}

}

}

新建一个模型。

#/info/model/user_model.php

class user_model extends Info_Model{

#声明一个读取数据库中所有用户数据的方法

#在此之前要在数据库中新建一个用户表‘user_info’并加入一些数据

public function getAllUserInfo(){

$sql = 'select * from user_info';

$data = $this->db->query($sql)->fetchAll();

return $data;

}

}

在自定义的控制器中加载该模型并调用上面声明的方法

class Welcome_Controller extends Info_Controller{

public function hello(){

#加载模型并且给一个别名。

$this->loadModel('user_model','user');

#调用该模型的方法(获取用户数据)

$userinfo = $this->user->getAllUserInfo();

var_dump($userinfo);

}

}

测试结果:

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值