做一个自己的MVC框架[php]
来源:互联网 发布:淘宝商城妈妈装 编辑:程序博客网 时间:2024/05/21 11:14
外包的活干多了,总有一些小项目,这些小项目甚至不需要考虑安全。这时候用框架显得浪费。自己手写原生代码又有些不太习惯(框架用多了,有时候连基本的都忘了,不能忘本啊。。。)
许久不更的博客。反正也没多少人看,哈~就当给自己一个马克,也希望能给一些刚踏入程序猿大军的新手们做到一个了解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).但入口文件设置基本信息
<?php #info/index.php: #声明项目根本目录 define("SERVER_ROOT",dirname(__FILE__)); #声明项目网址 define("SITE_ROOT","localhost/info"); #声明视图文件夹 define("VIEWS_ROOT",dirname(__FILE__).'views'); #声明控制器文件夹 define("CONTROLLER_ROOT",'/controllers'); #引入框架核心控制器 require_once(SERVER_ROOT . "/core/Info_Controller.php"); #引入框架核心模型 require_once(SERVER_ROOT . "/core/Info_Model.php"); #引入路由 require_once(SERVER_ROOT . "/core/route.php");
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
<?php #测试用完即删掉该文件 class Hello_Controller{ public function world(){ echo 'hello world'; } } ?>
测试结果如图:
2)控制器加载视图
前面已经做了URL到控制器和方法的路由,下面来做控制器加载视图。
因为PHP是一种可嵌入到HTML的脚本,所以我们可以直接在方法中include一个HTML,(好直白。。。)。同理,方法中所有在include之前声明的变量都可以直接用,但这也是一个弊端,即所有的变量都可以在HTML中使用。所以我们将include封装成一个方法,任何将要显示在HTML页面的变量都以参数的方式传给该方法。
考虑到该方法可能会被多次调用,所以封装为核心类的方法,这样每次新建一个方法只要继承核心类就可以调用。即在info_Controller.php中声明一个loadView的方法,之后controller文件夹下所有的类都extends Info_Controller即可:
<?php #核心类 info/core/Info_Controller.php class Info_Controller{ public function loadView($view,$data=NULL){ #拿到参数传入的数据 $data = $data; #所有视图文件都在VIEWS_ROOT中 require_once(VIEWS_ROOT . "/$view"); }}
<?php #用户自定义类 info/controller/test/welcome.php class Welcome_Controller extends Info_Controller{ public function hello(){ $data['key'] = 'value'; $this->loadView('welcome.html',$data); } }}
<!-- 视图文件 /info/views/welcome.html --><html> <head> </head> <body> <?php var_dump($data);?> <h1>helloworld</h1> </body></html>
测试结果:
3)控制器调用模型
模型层我们主要是用来进行数据库操作。首先我们要连接数据库。
连接数据库的信息,一般我们都放在单独的配置文件,连接的时候直接引入该文件即可。
<?php #/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类即可。
<?php #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)中加载视图一样,在核心控制器中封装一个加载模型的函数
<?php #/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(); } } } }
新建一个模型。
<?php #/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; } }
在自定义的控制器中加载该模型并调用上面声明的方法
<?php class Welcome_Controller extends Info_Controller{ public function hello(){ #加载模型并且给一个别名。 $this->loadModel('user_model','user'); #调用该模型的方法(获取用户数据) $userinfo = $this->user->getAllUserInfo(); var_dump($userinfo); } }
测试结果:
到这里基本上就结束了。
这只是一个简单的MVC。没有考虑的太多。欢迎指正。
附上代码链接:
http://download.csdn.net/detail/u013332865/9705768
- 做一个自己的MVC框架[php]
- 实现自己的MVC框架(php) 1
- 使用PHP开发自己的MVC框架
- php打造属于自己的MVC框架-
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- php打造属于自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用php搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- 使用PHP搭建自己的MVC框架
- PHP搭建自己的MVC框架 1
- PHP搭建自己的MVC框架 2
- 如何编写自己的PHP MVC 框架
- 封装一个自己的mvc框架
- 【旧代码整理】做的一个简单的php mvc框架
- 山科大 oj 提取缩略词
- 会话技术
- python基础教程-文件操作
- 查看硬件配置命令(ubuntu示例)
- java读写Properties属性文件公用方法
- 做一个自己的MVC框架[php]
- NUMA架构的CPU
- 输入一个数插入有序数组中
- 微信分享 解决留在微信时没有回调结果的问题(不保证所有的都成功)
- php 字符串大小写转换
- Java使用HtmlParse提取标签中的值
- 小米5的的开发环境配置
- 兔子产子问题
- 欢迎使用CSDN-markdown编辑器