说到php框架就不得不提MVC,现在主流框架都沿用的MVC的架构思想;
我们学php初都会学习MVC,学习其运行流程、学其面向对象的思想;
先来回顾一下MVC:
MVC概念
MVC包括控制器(Controller),模型(Model),视图(View)。
控制器的作用是调用模型和 视图,将模型产生的数据传递给视图,并让视图去显示
模型的作用是获取数据并处理返回数据
视图的作用是将取得的数据进行美化,并向用户终端输出
(2)执行过程
- 浏览者 -> 调用控制器,发出指令
- 控制器 -> 按指令选择合适的模型
- 模型 -> 按指令取数据
- 控制器 -> 按指令选视图
- 视图 -> 把取到的数据展示出来
composer之前MVC框架的加载方式都是使用的文件引入的方式(include);
再使用 spl_autoload_register()进行注册;
现在composer流行,我们写一个mvc框架就变得更加的简单,文件全部是用composer加载;
现在我们来编写一个简单的MVC框架;
首先定义下规则,看个人喜好:
- 所有文件都以小写命名;
- 命名空间以小写开头;
- 视图以小写开头;
- 控制器统一不带controller;
支持单模块独立绑定域名;
1、首先安装composer建议全局安装;具体参考composer官网
2、创建框架目录如下
app --- 应用目录(区分模块)
conf --- 配置目录(dev、pro、test)区分环境
libs --- 核心类库文件
public --- 公共目录(区分模块)
static --- 静态资源
3、项目新建立composer.json文件,内容如下:
{
"authors": [
{
"name": "yiijun",
"email": "251784425@qq.com"
}
],
"require": {
"php": ">=7.0.4"
},
"autoload": {
"psr-4": {"libs\\": "libs/","app\\":"app/"}
}
}
重点是autoload:目前我们这个框架需要自动加载的目录为,libs与app
4、cd 到项目目录下执行composer update
5、暂定项目名称为simple-php,编写解析路由核心类文件,libs/framework/simple.php,一个mvc的核心也就是这里了;
<?php
// +----------------------------------------------------------------------
// | Created by [ PhpStorm ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016.
// +----------------------------------------------------------------------
// | Create Time (2020-07-28 16:05)
// +----------------------------------------------------------------------
// | Author: 唐轶俊 <tangyijun@021.com>
// +----------------------------------------------------------------------
namespace libs\framework;
class Simple
{
protected $config = [];
public function __construct($config = [])
{
$this->config = $config;
}
public function run()
{
//路由解析
$this->route();
//设置错误级别
$this->setReporting();
}
public function route()
{
$controllerName = $this->config['controller'];
$actionName = $this->config['action'];
$params = [];
$url = $_SERVER['REQUEST_URI'];
$position = strpos($url, '?');
$url = $position === false ? $url : substr($url, 0, $position);
$url = trim($url, '/');
if ($url) {
$urlArray = explode('/', $url);
$urlArray = array_filter($urlArray);
//获取控制器名称
$controllerName = ucfirst($urlArray[0]);
array_shift($urlArray);
//获取方法名称
$actionName = $urlArray ? $urlArray[0] : $actionName;
array_shift($urlArray);
//获取参数
$params = $urlArray ? $urlArray : array();
}
//获取模块名称
$module = substr(APP_PATH,strrpos(str_replace('\\','/',APP_PATH),"/") + 1);
$controller = 'app\\'.$module.'\\controller\\'. $controllerName;
//过滤
if ($controller && !preg_match('/^[A-Za-z](\w|\.)*$/', $controller) && !class_exists($controller)) {
exit($controller . '控制器不存在');
}
if (!method_exists($controller, $actionName)) {
exit($actionName . '方法不存在');
}
$dispatch = new $controller($controllerName, $actionName);
call_user_func_array(array($dispatch, $actionName), $params);
}
public function setReporting()
{
if (APP_DEBUG === true) {
error_reporting(E_ALL);
ini_set('display_errors','On');
} else {
error_reporting(E_ALL);
ini_set('display_errors','Off');
ini_set('log_errors', 'On');
}
}
}
6、首先我们在app目录下建立文件夹admin模块作为后台;
7、建立文件init.php,定义常量和环境变量,加载composer
<?php
// +----------------------------------------------------------------------
// | Created by [ PhpStorm ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016.
// +----------------------------------------------------------------------
// | Create Time (2020-07-28 16:05)
// +----------------------------------------------------------------------
// | Author: 唐轶俊 <tangyijun@021.com>
// +----------------------------------------------------------------------
$host_name = gethostname();
if(in_array($host_name, ['VM_48_39_centos'])) {
define('LIB_ENV', 'pro');
} else if(in_array($host_name, ['10-9-115-74'])) {
define('LIB_ENV', 'test');
} else {
define('LIB_ENV', 'dev');
}
define('APP_PATH', dirname(__FILE__));
define('APP_DEBUG', true);
require __DIR__ . '/../../vendor/autoload.php';
//加载配置
$config = require_once __DIR__ . '/../../conf/'.LIB_ENV.'/conf_admin.php';
$app = new \libs\framework\Simple($config);
8、建立项目入口文件:publicadminindex.php,运行项目
require __DIR__ . '/../../app/admin/init.php';
$app->run();
9、建立基础控制器、controller.php 放在:/libs/franework/base/controller.php
<?php
// +----------------------------------------------------------------------
// | Created by [ PhpStorm ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016.
// +----------------------------------------------------------------------
// | Create Time (2020-07-29 10:06)
// +----------------------------------------------------------------------
// | Author: 唐轶俊 <tangyijun@021.com>
// +----------------------------------------------------------------------
namespace libs\framework\base;
class Controller
{
protected $controller;
protected $action;
protected $view;
public function __construct($controller,$action)
{
$this->controller = $controller;
$this->action = $action;
$this->view = new View($this->controller,$this->action);
}
public function assign($name, $value)
{
$this->view->assign($name, $value);
}
public function render()
{
$this->view->render();
}
}
10、建立基础视图、controller.php 放在:/libs/framework/base/view.php
<?php
// +----------------------------------------------------------------------
// | Created by [ PhpStorm ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016.
// +----------------------------------------------------------------------
// | Create Time (2020-07-29 9:57)
// +----------------------------------------------------------------------
// | Author: 唐轶俊 <tangyijun@021.com>
// +----------------------------------------------------------------------
namespace libs\framework\base;
class View
{
protected $controller;
protected $action;
protected $variables = [];
public function __construct($controller,$action)
{
$this->controller = $controller;
$this->action = $action;
}
/**
* @param $name
* @param $value
* 渲染变量
*/
public function assign($name,$value)
{
$this->variables[$name] = $value;
}
/**
* 加载视图
*/
public function render()
{
//变量赋值
extract($this->variables);
//获取视图路径
$layout = APP_PATH . '/view/' . strtolower($this->controller) . '/' . ucwords($this->action) . '.html';
if (is_file($layout)) {
include $layout;
} else {
echo "<h1>无法找到视图文件</h1>";
}
}
}
11、在admin模块中建立首页控制器,/app/admin/controller/index.php
<?php
// +----------------------------------------------------------------------
// | Created by [ PhpStorm ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016.
// +----------------------------------------------------------------------
// | Create Time (2020-07-28 17:14)
// +----------------------------------------------------------------------
// | Author: 唐轶俊 <tangyijun@021.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;
use libs\framework\base\Controller;
class Index extends Controller
{
public function index()
{
$this->assign('hello','hello world');
$this->render();
}
}
12、在admin模块中建立首页视图,/app/admin/view/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<?php echo $hello?>
</body>
</html>
13、绑定域名:
<VirtualHost *:80>
DocumentRoot "D:\phpStudy\WWW\simple-php\public\admin"
ServerName admin.simple-php.com
ServerAlias
<Directory "D:\phpStudy\WWW\simple-php\public\admin">
Options FollowSymLinks ExecCGI
AllowOverride All
Order allow,deny
Allow from all
Require all granted
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php #重定向
</Directory>
</VirtualHost>
14、访问域名
该框架的核心就是实用composer加载类文件、而不用实用引入的方式;使代码更加简洁、用起来更加的方便;
该框架我封装了一些常用的核心类文件;
比如:
- redis
- curl
- upload
- redis
- session
- log
- db
- apcu
- 通用函数
等类文件,可以直接使用;
项目放在githup上地址为:
学习了,赞一个