ThinkPHP支持传统的MVC(Model-View-Controller
)模式以及流行的MVVM(Model-View-ViewModel
)模式的应用开发
MVC 软件系统分为三个基本部分:模型(Model
)、视图(View
)和控制器(Controller
)
ThinkPHP 是一个典型的 MVC 架构
控制器 - 负责转发请求,对请求进行处理。
视图 - 界面设计人员进行图形界面设计。
模型 - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
项目访问路径:www.xxx.com/index.php/index/index
也可以直接访问http://www.xxx.com/
其中 index.php 入口文件 index 控制器 index 操作
注意:官方的实例Index\index.php控制器中的hello方法就不能以这种方式访问,因为该控制器方法在路由中进行了设置,需要通过http://www.zhang.com/hello/zhang进行访问,
http://www.zhang.com/Index/hello是无法访问到的。
路由 route/app.php
Route::get('think', function () { return 'hello,ThinkPHP6!';});Route::get('hello/:name', 'index/hello');/* 访问地址http://zhang.com/index.php/thinkhttp://zhang.com/index.php/hello/zhang*/
├─app 应用目录│ ├─controller 控制器目录│ ├─model 模型目录│ ├─ ... 更多类库目录│ ││ ├─common.php 公共函数文件│ └─event.php 事件定义文件│├─config 配置目录│ ├─app.php 应用配置│ ├─cache.php 缓存配置│ ├─console.php 控制台配置│ ├─cookie.php Cookie配置│ ├─database.php 数据库配置│ ├─filesystem.php 文件磁盘配置│ ├─lang.php 多语言配置│ ├─log.php 日志配置│ ├─middleware.php 中间件配置│ ├─route.php URL和路由配置│ ├─session.php Session配置│ ├─trace.php Trace配置│ └─view.php 视图配置│├─view 视图目录├─route 路由定义目录│ ├─route.php 路由定义文件│ └─ ...│├─public WEB目录(对外访问目录)│ ├─index.php 入口文件│ ├─router.php 快速测试文件│ └─.htaccess 用于apache的重写│├─extend 扩展类库目录├─runtime 应用的运行时目录(可写,可定制)├─vendor Composer类库目录├─.example.env 环境变量示例文件├─composer.json composer 定义文件├─LICENSE.txt 授权说明文件├─README.md README 文件├─think 命令行入口文件
视图功能由\think\View类
配合视图驱动(也即模板引擎驱动)类一起完成,新版仅内置了PHP原生模板引擎(主要用于内置的异常页面输出),如果需要使用其它的模板引擎需要单独安装相应的模板引擎扩展
ThinkPHP6已独立出一套模版,命名为:ThinkTemplate模板引擎;
使用think-template模板引擎,需安装think-view;
composer require topthink/think-view
视图目录可以在根目录,也可以在app应用目录
控制器类名称对应视图文件夹名称,控制器中方法名称对应视图文件名称
app\controller\Index.php
<?phpnamespace app\controller;use app\BaseController;use think\facade\View;class Index extends BaseController{ public function index() { return View::fetch(); }}
要使用View,必须先引入 think\facade\View
门面类
fetch 方法渲染页面
参数:静态页面的路径,默认对应的静态页面
app\controller\Index.php代码
<?phpnamespace app\controller;use app\BaseController;use think\facade\View;class Index extends BaseController{ public function index(){ return View::fetch(); }}
view\Index\index.html代码
<!DOCTYPE html><html><head> <title>你好</title></head><body> <h1>Hello World!</h1></body></html>
备:Index类对应view下面的目录
备:index方法对应view下面的目录里的静态文件
assign 方法赋值属于全局变量赋值
模版输出 {$name}全局变量
app\controller\Index.php代码
<?phpnamespace app\controller;use think\facade\View;class Index { public function index() { // 模板变量赋值 // View:assign('name','zhang'); // View::assign('email','zhang@qq.com'); // 或者数组形式批量赋值 View::assign([ 'name'=>'zhang', 'email'=>'zhang@qq.com' ]); // 模板输出 return View::fetch(); }}
view\Index\index.html代码
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>ThinkPHP6</title> </head> <body> 姓名:{$name} <br> 邮箱:{$email} </body></html>
public目录为唯一的web可访问目录
把资源文件放到public/static
中
入口文件,默认为index.php
public/index.php
<?php// [ 应用入口文件 ]namespace think;require __DIR__ . '/../vendor/autoload.php';// 执行HTTP应用并响应$http = (new App())->http;$response = $http->run();$response->send();$http->end($response);
把html页面放到ThinkPHP框架里
此页面是静态文件
<!DOCTYPE html><html><head> <title>列表页</title> <link rel="stylesheet" type="text/css" href="layui/css/layui.css"> <script type="text/javascript" src="layui/layui.js"></script> <style type="text/css"> .header { width: 100%; height: 50px; line-height: 50px; background: #2e6da4; color: #ffffff; } .title { margin-left: 20px; font-size: 20px; } .userinfo { float: right; margin-right: 10px; } .userinfo a { color: #ffffff; } .menu { width: 200px; background: #333744; position: absolute; } .main { position: absolute; left: 200px; right: 0px; } .layui-collapse { border: none; } .layui-colla-item { border-top: none; } .layui-colla-title { background: #42485b; color: #ffffff; } .layui-colla-content { border-top: none; padding: 0px; } .content span { background: #009688; margin-left: 30px; padding: 10px; color: #ffffff; } .content div { border-bottom: solid 2px #009688; margin-top: 8px; } .content button { float: right; margin-top: -5px; } </style></head><body> <div> <span><span style="font-size: 20px;">XXX</span>--后台管理系统</span> <span>【欧阳克】<span><a href="javascript:;">退出</a></span></span> </div> <div id="menu"> <div lay-accordion> <div> <h2>商城管理</h2> <div class="layui-colla-content layui-show"> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> </ul> </div> </div> <div> <h2>商城管理</h2> <div> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> </ul> </div> </div> <div> <h2>商城管理</h2> <div> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> <li><a href="list.html">商品列表</a></li> </ul> </div> </div> </div> </div> <div style="padding:10px;"> <div> <span>商品列表</span> <div></div> </div> <table> <thead> <tr> <th>ID</th> <th>商品标题</th> <th>分类</th> <th>价格</th> <th>状态</th> <th>添加时间</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>熙世界2019秋冬新款长袖杏色上衣连帽宽松刺绣文艺落肩袖加厚卫衣BF风</td> <td>女装</td> <td>189</td> <td>开启</td> <td>2019-12-12</td> </tr> <tr> <td>2</td> <td>秋水伊人双面呢冬装2019年新款女装气质西装领撞色羊毛大衣外套女</td> <td>女装</td> <td>699</td> <td>开启</td> <td>2019-12-12</td> </tr> <tr> <td>3</td> <td>秋水伊人双面呢冬装2019年新款女装气质西装领撞色羊毛大衣外套女</td> <td>女装</td> <td>699</td> <td>开启</td> <td>2019-12-12</td> </tr> <tr> <td>4</td> <td>秋水伊人双面呢冬装2019年新款女装气质西装领撞色羊毛大衣外套女</td> <td>女装</td> <td>699</td> <td>开启</td> <td>2019-12-12</td> </tr> <tr> <td>5</td> <td>秋水伊人双面呢冬装2019年新款女装气质西装领撞色羊毛大衣外套女</td> <td>女装</td> <td>699</td> <td>关闭</td> <td>2019-12-12</td> </tr> <tr> <td>6</td> <td>秋水伊人双面呢冬装2019年新款女装气质西装领撞色羊毛大衣外套女</td> <td>女装</td> <td>699</td> <td>开启</td> <td>2019-12-12</td> </tr> </tbody> </table> </div></body></html><script> layui.use(['element', 'layer', 'laypage'], function() { var element = layui.element; var laypage = layui.laypage; $ = layui.jquery; layer = layui.layer; resetMenuHeight(); }); // 重新设置菜单容器高度 function resetMenuHeight() { var height = document.documentElement.clientHeight - 50; $('#menu').height(height); }</script>
controller代码,此数据为测试数据,后面会从数据库中读取
<?phpnamespace app\controller;use think\facade\View;class Index{ public function index(){ $title = '商城'; $login = '欧阳克'; $left = [ [ 'title' => '商品管理', 'lists' => [ [ 'id' => 1, 'title' => '商品列表', ], [ 'id' => 2, 'title' => '商品分类', ] ] ], [ 'title' => '用户管理', 'lists' => [ [ 'id' => 3, 'title' => '用户列表', ], [ 'id' => 4, 'title' => '购物车', ], [ 'id' => 5, 'title' => '用户地址', ], [ 'id' => 6, 'title' => '订单管理', ] ] ], [ 'title' => '后台管理', 'lists' => [ [ 'id' => 7, 'title' => '管理员列表', ], [ 'id' => 8, 'title' => '个人中心', ], [ 'id' => 9, 'title' => '左侧菜单列', ] ] ] ]; $right = [ [ 'id' => 1, 'title' => '熙世界2019秋冬新款长袖杏色上衣连帽宽松刺绣文艺落肩袖加厚卫衣BF风', 'cat' => '女装', 'price' => 189, 'discount' => 6, // 'status' => 1, 'status' => '开启', 'add_time' => '2019-12-12', // 'add_time' => '1576080000' ], [ 'id' => 2, 'title' => '秋水伊人双面呢冬装2019年新款女装气质西装领撞色羊毛大衣外套女', 'cat' => '女装', 'price' => 699, 'discount' => 7, // 'status' => 1, 'status' => '开启', 'add_time' => '2019-12-12', // 'add_time' => '1576080000' ], [ 'id' => 3, 'title' => '微弹中高腰直脚牛仔裤男', 'cat' => '男装', 'price' => 179, 'discount' => 8, // 'status' => 2, 'status' => '关闭', 'add_time' => '2019-12-12', // 'add_time' => '1576080000' ], [ 'id' => 1, 'title' => '男士长袖t恤秋季圆领黑白体恤T 纯色上衣服打底衫', 'cat' => '男装', 'price' => 99, 'discount' => 9, // 'status' => 1, 'status' => '开启', 'add_time' => '2019-12-12', // 'add_time' => '1576080000' ], ]; View::assign([ 'title' => $title, 'login' => $login, 'left' => $left, 'right' => $right ]); return View::fetch(); }}
view代码,控制器数据在视图中使用
<!DOCTYPE html><html><head> <title>{$title}--后台管理系统</title> <link rel="stylesheet" type="text/css" href="static/layui/css/layui.css"> <script type="text/javascript" src="static/layui/layui.js"></script> <style type="text/css"> .header { width: 100%; height: 50px; line-height: 50px; background: #2e6da4; color: #ffffff; } .title { margin-left: 20px; font-size: 20px; } .userinfo { float: right; margin-right: 10px; } .userinfo a { color: #ffffff; } .menu { width: 200px; background: #333744; position: absolute; } .main { position: absolute; left: 200px; right: 0px; } .layui-collapse { border: none; } .layui-colla-item { border-top: none; } .layui-colla-title { background: #42485b; color: #ffffff; } .layui-colla-content { border-top: none; padding: 0px; } .content span { background: #009688; margin-left: 30px; padding: 10px; color: #ffffff; } .content div { border-bottom: solid 2px #009688; margin-top: 8px; } .content button { float: right; margin-top: -5px; } </style></head><body> <div> <span><span style="font-size: 20px;">{$title}</span>--后台管理系统</span> <span>【{$login}】<span><a href="javascript:;">退出</a></span></span> </div> <div id="menu"> <div lay-accordion> <div> <h2>{$left.0.title}</h2> <div class="layui-colla-content layui-show"> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li><a href="index.html">{$left.0.lists.0.title}</a></li> <li><a href="index.html">{$left.0.lists.1.title}</a></li> </ul> </div> </div> <div> <h2>{$left[1]['title']}</h2> <div> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li><a href="index.html">{$left.1.lists.0.title}</a></li> <li><a href="index.html">{$left.1.lists.1.title}</a></li> <li><a href="index.html">{$left.1.lists.2.title}</a></li> <li><a href="index.html">{$left.1.lists.3.title}</a></li> </ul> </div> </div> <div> <h2>{$left.2.title}</h2> <div> <ul class="layui-nav layui-nav-tree" lay-filter="test"> <li><a href="index.html">{$left.2.lists.0.title}</a></li> <li><a href="index.html">{$left.2.lists.1.title}</a></li> <li><a href="index.html">{$left.2.lists.2.title}</a></li> </ul> </div> </div> </div> </div> <div style="padding:10px;"> <div> <span>商品列表</span> <div></div> </div> <table> <thead> <tr> <th>ID</th> <th>商品标题</th> <th>分类</th> <th>价格</th> <th>折扣</th> <th>状态</th> <th>添加时间</th> </tr> </thead> <tbody> <tr> <td>{$right.0.id}</td> <td>{$right.0.title}</td> <td>{$right.0.cat}</td> <td>{$right.0.price}</td> <td>{$right.0.discount}</td> <td>{$right.0.status}</td> <td>{$right.0.add_time}</td> </tr> <tr> <td>{$right.1.id}</td> <td>{$right.1.title}</td> <td>{$right.1.cat}</td> <td>{$right.1.price}</td> <td>{$right.1.discount}</td> <td>{$right.1.status}</td> <td>{$right.1.add_time}</td> </tr> <tr> <td>{$right.2.id}</td> <td>{$right.2.title}</td> <td>{$right.2.cat}</td> <td>{$right.2.price}</td> <td>{$right.2.discount}</td> <td>{$right.2.status}</td> <td>{$right.2.add_time}</td> </tr> <tr> <td>{$right.3.id}</td> <td>{$right.3.title}</td> <td>{$right.3.cat}</td> <td>{$right.3.price}</td> <td>{$right.3.discount}</td> <td>{$right.3.status}</td> <td>{$right.3.add_time}</td> </tr> </tbody> </table> </div></body></html><script> layui.use(['element', 'layer', 'laypage'], function() { var element = layui.element; var laypage = layui.laypage; $ = layui.jquery; layer = layui.layer; resetMenuHeight(); }); // 重新设置菜单容器高度 function resetMenuHeight() { var height = document.documentElement.clientHeight - 50; $('#menu').height(height); }</script>
预览地址:http://zhang.com