现如今我们php 框架有很多比如:
laravel(优雅::老司机)
yii2.0
TP
CI
那么既然有这么多优秀的框架我们为什么还要自己去封装一个属于我们自己的MVC框架呢?
1、让我们的开发过程更加的效率
2、让我们更加清楚的理解代码运行的流程
3、实现自我的最佳方式(走向架构师的一小步)!!
那么我们实现mvc的流程是什么呢?
入口文件---定义常量---引入函数---自动加载类----启动框架--路由解析---加载控制器---返回结果
下面我们开始编写入口文件
使用到的函数:
realpath();
该函数删除所有符号连接(比如 '/./', '/../' 以及多余的 '/'),返回绝对路径名
getcwd();
该函数返回当前工作目录
ini_set();
该函数具有更改PHP.ini设置的功能。此函数接收两个参数:需要调整的配置变量名,以及变量的新值
spl_autoload_register();
该函数与__autoload作用一样都是当我们实例化一个未定义的类时,就会触发此函数
extract();
extract() 函数从数组中将变量导入到当前的符号表。
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
第二个参数 type 用于指定当某个变量已经存在,而数组中又有同名元素时,extract() 函数如何对待这样的冲突。
该函数返回成功导入到符号表中的变量数目。
<?php
/**
* 入口文件
* 1、定义文件
* 2、加载函数库
* 3、启动框架
*/
//根目录
define('PATH',getcwd());
//核心文件
define('CORE',PATH.'/core');
//项目文件
define('APP',PATH.'/app');
//定义模块
define('MODULE','app');
//开启错误调试
define('DEBUG',true);
if(DEBUG){
ini_set('display_error','On');
}else{
ini_set('display_error','off');
}
//加载类库
include CORE.'/common/function.php';
//核心文件
include CORE.'/run.php';
//自动加载类库 注意load 方法必须是一个静态方法
spl_autoload_register('\core\run::load');
//运行框架 就是运行核心文件的一个方法
\core\run::run();
?>
类库文件 就是一个简单的输出方法
core/common/function.php
p(var):void
<?php
function p($var){
if(is_bool($var)){
var_dump($var);
}else if(is_null($var)){
var_dump(NULL);
}else{
echo "<pre style='postion:relative;z-index:1000;padding:10px;border-radius:5px;background:#F5F5F5;border:1px solid #aaa;font-size:14px;line-height:18px;opacity:0.9;'>".print_r($var,true)."</pre>";
}
}
?>
核心文件
core/run.php
run 方法主要是实例化路由类
load 的方法自动加载类 (include 实例化类所对应文件)
assign 方法是传送数据
display 方法是渲染页面 主要用到了 extract()函数 实现
<?php
namespace core;
class run{
//设置自动加载类数组
public static $classMap = array();
//设置传值属性
public $assign;
static public function run(){
//实例化路由
$route = new \core\lib\route();
$controllerClass = $route->controller;
$action = $route->action;
//控制器文件 D:\newmvc/app/controllers/siteController.php
$ctrFile = APP.'/controllers/'.$controllerClass.'Controller.php';
//实例化控制器类 \APP\controllers\siteController
$ctrClass = '\\'.MODULE.'\controllers\\'.$controllerClass.'Controller';
if(is_file($ctrFile)){
include($ctrFile);
$ctrl = new $ctrClass();
$ctrl->$action();
}else{
throw new \Exception('找不到控制器'.$controllerClass);
}
}
/**
* [自动加载方法]
* @return [void]
*/
static public function load($class){
//p($class);
//p(PATH.$class.'.php');
//自动加载类库
// new \core\route();
// $clas = '\core\route';
//PATH.'/core/route.php'
//如果类名存在就返回true
if(isset($classMap[$class])){
return true;
}else{
//加载类
//将类名格式进行转换
str_replace('\\','/',$class);
$file = PATH.'/'.$class.'.php';
if(is_file($file)){
// p($file);exit;
include $file;
self::$classMap[$class] = $class;
}else{
return false;
}
}
}
/**
* 视图传值方法
* @param [type] $name [视图变量]
* @param [type] $value [控制器变量]
* @return [array] [所传值]
*/
public function assign($name,$value){
$this->assign[$name] = $value;
}
/**
* [渲染模板页面]
* @param [type] $file [视图文件]
* @return [void]
*/
public function display($file){
$file = APP.'/views/'.$file;
// p($file);
if(is_file($file)){
extract($this->assign);
include $file;
}
}
}
?>
core/lib/route.php
处理路由格式以及设置默认控制器以及方法
<?php
namespace core\lib;
class route
{
public $controller;
public $action;
public function __construct(){
/**
* 1、隐藏index.php
* 2、获取URL 参数部分
* 3、返回对应的控制器和方法
*/
if(isset($_SERVER['REQUEST_URI'])&&$_SERVER['REQUEST_URI']!="/"){
//获取当前url /index/index;
$path = $_SERVER['REQUEST_URI'];
//处理url
$pathArray = explode('/',trim($path,'/'));
if(isset($pathArray[0])){
$this->controller = $pathArray[0];
unset($pathArray[0]);
}
if(isset($pathArray[1])){
$this->action = $pathArray[1];
unset($pathArray[1]);
}else{
//设置默认方法
$this->action = "index";
}
//键名从2开始
$count = count($pathArray) + 2;
$i = 2;
while($i < $count){
//$i+1 是值的位置
if(isset($pathArray[$i+1])){
$_GET[$pathArray[$i]] = $pathArray[$i + 1];
}
$i = $i + 2;
}
}else{
//设置默认
$this->controller = "index";
$this->action = "index";
}
}
}
?>
app\controllers\IndexController.php
控制器的连接数据以及渲染视图
<?php
namespace app\controllers;
class IndexController extends \core\run
{
public function index(){
// p("this is a action");
//连接数据库
// $model = new \core\lib\model();
// $sql = "SELECT * FROM message";
// $re = $model->query($sql);
// p($re->fetchAll());
$data = "hahahaa";
//视图
$this->assign('data',$data);
$this->display('index.html');
}
public function show(){
p('jiaoweiwei');
}
}
?>
core/lib/model.php 连接数库
继承pdo来连接数据库
<?php
namespace core\lib;
class model extends \PDO{
public function __construct(){
$dsn = 'mysql:host=localhost;dbname=yii3';
$userName = 'root';
$passWord= 'root';
try{
parent::__construct($dsn,$userName,$passWord);
} catch (\PDOException $e){
p($e->getMessage());
}
}
}
?>
.htaccess
#开启重写引擎
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f [NC]
RewriteRule ^(.*)$ index.php/$1 [L]
这样就实现了一个简单的mvc框架
效果演示:
.