Blogger Information
Blog 32
fans 0
comment 0
visits 27680
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
用composer搭建简单框架
Yang_Sir
Original
1259 people have browsed it
  • 这是一个简单的MVC框架
  • 使用composer管理依赖的组件。本次使用了以下组件
类型 组件名称 简介 安装
模型组件 catfan/medoo 轻量级的PHP数据库框架 composer require catfan/medoo
视图模板组件 twig/twig 灵活、快速、安全的PHP模板语言 composer require twig/twig
路由组件 noahbuscher/macaw 非常简单的路由器 https://github.com/NoahBuscher/Macaw

noahbuscher/macaw,我直接require下载失败,在composer.json文件中添加
“require”: {
“noahbuscher/macaw”: “dev-master”
}
然后执行composer update命令,还要了github密钥[/尴尬],最终下载成功。

  • 使用组件可以快速搭建框架,但还是有很多地方要学习,如路径,组件的依赖,还有每个组件的开发文档,都是新的东西。有的组件框架挺大,依赖很多,下载后都使用失败了
  • comoposer的使用、还有服务器的设置,如.htaccess文件配置,需要学习的还很多

1.目录结构

  • app下即MVC框架成员,控制器、模型、视图
  • config放置配置文件,当前只有一个数据库配置
  • core核心类库,外部依赖的组件等都在这里处理
  • public外部访问目录
  • vender通过composer安装的组件都存放在此

2.mvc框架

2.1控制器

  • 在controller目录下创建Index.php控制器文件,处理前端发来的各种请求,并返回
  • 在控制器中会用到视图和模型对象,从模型中获取数据,在视图中展示

    1. <?php
    2. namespace app\controller;
    3. use app\model\Goods;
    4. use core\View;
    5. //控制器
    6. class Index
    7. {
    8. /**
    9. * 展示首页
    10. */
    11. public function index()
    12. {
    13. $goods = new Goods;
    14. $data = $goods->getData();
    15. $view = new View;
    16. echo $view->templete->render('/index/index.html',['data'=>$data]);
    17. }
    18. /**
    19. * 删除一条记录
    20. * 刷新页面
    21. */
    22. public function delete($id){
    23. $goods = new Goods;
    24. if(!empty($id)){
    25. $row = $goods->delete($id);
    26. if($row){
    27. echo "<script>alert('删除成功')</script>";
    28. }else{
    29. echo "<script>alert('删除失败')</script>";
    30. }
    31. }else{
    32. echo "<script>alert('格式错误')</script>";
    33. }
    34. return $this->index();
    35. }
    36. public function edit($id){
    37. $goods = new Goods;
    38. $view = new View;
    39. $data = $goods->edit($id);
    40. echo $view->templete->render('index/edit.html',['data'=>$data]);
    41. }
    42. public function update($id){
    43. if(isset($_POST['id'])){
    44. $data = $_POST;
    45. unset($data['id']);//去掉id
    46. $goods = new Goods;
    47. $view = new View;
    48. $row = $goods->update($data,$id);
    49. if($row==1){
    50. echo "<script>alert('更新成功')</script>";
    51. }else{
    52. echo "<script>alert('更新失败')</script>";
    53. }
    54. }
    55. return $this->index();
    56. }
    57. }

2.2模型

  • model目录下创建Goods.php,对应数据库表goods。用于处理数据
  • Goods模型继承核心类库core下的Model类

goods.php

  1. <?php
  2. namespace app\model;
  3. use core\Model;
  4. //模型
  5. class Goods extends Model
  6. {
  7. private $table = 'goods';//表名
  8. //获取多条记录
  9. public function getData(){
  10. $data = parent::select($this->table,'*',["LIMIT"=>15]);
  11. return $data;
  12. }
  13. //删除一条记录
  14. public function delete($id,$table='')
  15. {
  16. $obj = parent::delete($this->table,['id'=>$id]);
  17. return $obj->rowCount();
  18. }
  19. //编辑商品信息,根据ID获取一条数据
  20. public function edit($id){
  21. $data = parent::get($this->table,'*',["id"=>$id]);
  22. return $data;
  23. }
  24. //更新一条数据
  25. public function update($data, $id, $where = null)
  26. {
  27. $obj = parent::update($this->table,$data,["id"=>$id]);
  28. return $obj->rowCount();
  29. }
  30. }
  • Model类继承外部引入的模型组件medoo
  • 在Model中重写构造方法,在构造方法中引入配置文件database.php

Model.php

  1. <?php
  2. namespace core;
  3. use Medoo\Medoo;
  4. //公共模型
  5. class Model extends Medoo
  6. {
  7. protected $config = [];
  8. public function __construct()
  9. {
  10. $this->config = require('../config/database.php');
  11. parent::__construct($this->config);
  12. }
  13. }

2.3视图模板

  • 在view目录下创建index文件夹,存放index控制器的视图文件
  • 在core核心类库中创建View.php作为公共的视图类,该类继承外部引入的twig模板组件。
  • 创建构造方法,获取twig的模板对象。

View.php

  1. <?php
  2. namespace core;
  3. use Twig\Environment;
  4. use Twig\Loader\FilesystemLoader;
  5. //公共视图模板
  6. class View extends Environment
  7. {
  8. public static $templete;
  9. public function __construct()
  10. {
  11. $loader = new FilesystemLoader('../app/view');
  12. $this->templete = new Environment($loader);
  13. }
  14. }
  15. - view/index目录下创建两个视图文件,首页index.html、编辑页edit.html
  16. - 使用twig模板语言输出数据
  17. index.html
  18. ```html
  19. <!DOCTYPE html>
  20. <html lang="en">
  21. <head>
  22. <meta charset="UTF-8" />
  23. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  24. <title>商品信息管理</title>
  25. <style>
  26. body {
  27. display: flex;
  28. flex-flow: column nowrap;
  29. align-items: center;
  30. }
  31. form {
  32. display: flex;
  33. flex-flow: row wrap;
  34. }
  35. form > section {
  36. margin: 10px;
  37. display: flex;
  38. flex-flow: row nowrap;
  39. }
  40. table {
  41. margin-top: 30px;
  42. width: 1000px;
  43. font-family: verdana, arial, sans-serif;
  44. font-size: 11px;
  45. color: #333333;
  46. border-width: 1px;
  47. border-color: #666666;
  48. border-collapse: collapse;
  49. }
  50. table > thead {
  51. background-color: #00ffff;
  52. }
  53. table th {
  54. border-width: 1px;
  55. padding: 8px;
  56. border-style: solid;
  57. border-color: #666666;
  58. }
  59. table td {
  60. border-width: 1px;
  61. padding: 8px;
  62. border-style: solid;
  63. border-color: #666666;
  64. background-color: #ffffff;
  65. text-align: center;
  66. }
  67. tfoot > tr,
  68. tfoot > tr > td {
  69. width: initial;
  70. }
  71. </style>
  72. </head>
  73. <body>
  74. <hr />
  75. <hr />
  76. <form
  77. action="<?php echo $_SERVER['PHP_SELF'] ?>"
  78. class="queryterms"
  79. method="POST"
  80. >
  81. <section>
  82. <label for="goodsname">商品名称:</label>
  83. <input type="text" name="goodsname" id="goodsname" value="" />
  84. </section>
  85. <section>
  86. <label for="goodsmodel">商品型号:</label>
  87. <input type="text" name="goodsmodel" id="goodsmodel" value="" />
  88. </section>
  89. <section>
  90. <button>查询</button>
  91. </section>
  92. </form>
  93. <div>
  94. <table>
  95. <thead>
  96. <tr>
  97. <th>ID</th>
  98. <th>名称</th>
  99. <th>型号</th>
  100. <th>价格</th>
  101. <th>数量</th>
  102. <th>状态</th>
  103. <th>操作</th>
  104. </tr>
  105. </thead>
  106. <tbody>
  107. {% for goods in data %}
  108. <tr>
  109. <td>{{ goods.id|e }}</td>
  110. <td>{{ goods.name|e }}</td>
  111. <td>{{ goods.model|e }}</td>
  112. <td>{{ goods.price|e }}</td>
  113. <td>{{ goods.number|e }}</td>
  114. <td>{{ goods.status|e }}</td>
  115. <td>
  116. <a href="/index/edit/{{ goods.id|e }}">编辑</a>
  117. &nbsp;&nbsp;&nbsp;
  118. <a href="/index/delete/{{ goods.id|e }}">删除</a>
  119. </td>
  120. </tr>
  121. {% endfor %}
  122. </tbody>
  123. <tfoot>
  124. <tr>
  125. <td colspan="7"></td>
  126. </tr>
  127. </tfoot>
  128. </table>
  129. </div>
  130. </body>
  131. </html>

edit.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=xiug, initial-scale=1.0" />
  6. <title>修改商品信息</title>
  7. <style>
  8. body {
  9. margin: 0;
  10. text-align: center;
  11. display: flex;
  12. flex-flow: column nowrap;
  13. align-items: center;
  14. }
  15. form {
  16. background-color: lightcyan;
  17. border: 1px solid #c0c0c0;
  18. width: 600px;
  19. display: flex;
  20. flex-flow: column nowrap;
  21. align-items: center;
  22. padding: 30px;
  23. }
  24. form > section {
  25. width: 80%;
  26. margin: 30px 0;
  27. display: grid;
  28. grid-template-columns: 200px 300px;
  29. font-size: 1.2em;
  30. }
  31. form > section input {
  32. font-size: 1.2em;
  33. }
  34. button {
  35. background-color: #bbd6e4;
  36. width: 200px;
  37. margin-top: 30px;
  38. padding: 10px;
  39. border-radius: 5px;
  40. }
  41. </style>
  42. </head>
  43. <body>
  44. <h1>修改商品信息</h1>
  45. <form action="/index/update/{{data.id}}" method="POST">
  46. <input type="hidden" name="id" value="{{data.id}}" />
  47. <section>
  48. <label for="name">商品名称:</label>
  49. <input type="text" name="name" id="name" value="{{data.name}}" />
  50. </section>
  51. <section>
  52. <label for="model">商品型号:</label>
  53. <input type="text" name="model" id="model" value="{{data.model}}" />
  54. </section>
  55. <section>
  56. <label for="price">价格:</label>
  57. <input type="text" name="price" id="price" value="{{data.price}}" />
  58. </section>
  59. <section>
  60. <label for="number">数量:</label>
  61. <input type="text" name="number" id="number" value="{{data.number}}" />
  62. </section>
  63. <section>
  64. <label for="status">状态:</label>
  65. <input type="text" name="status" id="status" value="{{data.status}}" />
  66. </section>
  67. <div class="button">
  68. <button type="submit">提交</button>
  69. </div>
  70. </form>
  71. </body>
  72. </html>

3.路由

  • 在core目录下创建routes.php文件
  • 在routes.php文件中创建NoahBuscher\Macaw路由器对象
  • 通过get方法设置路由,该方法有两个参数route和callback(或控制器方法路径)
  1. <?php
  2. name core;
  3. use NoahBuscher\Macaw\Macaw;
  4. //默认首页
  5. Macaw::get('/','app\controller\Index@index');
  6. //删除
  7. Macaw::get('index/delete/(:num)','app\controller\Index@delete');
  8. //编辑
  9. Macaw::get('index/edit/(:num)','app\controller\Index@edit');
  10. //更新
  11. Macaw::post('index/update/(:num)','app\controller\Index@update');
  12. // Macaw::get('(:all)',function($fu){
  13. // echo '未匹配到路由'.$fu;
  14. // });
  15. Macaw::dispatch();

4.composer自动加载

在正式访问之前还得把创建的几个类在composer.json文件中做好类库映射,然后在终端执行composer dump命令更新,才能实现自动加载。
把以下内容添加到composer.json文件中

  1. "autoload": {
  2. "psr-4": {
  3. "app\\": "app",
  4. "core\\": "core",
  5. "app\\controller\\": "app/controller",
  6. "app\\model\\": "app/model",
  7. "app\\view\\": "app/view"
  8. }
  9. }

5. 访问

  • 通过phpstudy创建一个网站,www.compo.edu,根目录指向comp目录下的public目录
  • public目录下创建index.php,即为该网站的入口文件
  • 另外还需要public目录下创建.htaccess文件,针对当前网站做访问配置

index.php

  1. <?php
  2. //包含进composer自动加载文件
  3. require'../vendor/autoload.php';
  4. //包含进路由器文件
  5. require '../core/routes.php';

.htaccess

  1. RewriteEngine On
  2. RewriteBase /
  3. # Allow any files or directories that exist to be displayed directly
  4. RewriteCond %{REQUEST_FILENAME} !-f
  5. RewriteCond %{REQUEST_FILENAME} !-d
  6. RewriteRule ^(.*)$ index.php?$1 [QSA,L]

效果图

访问 www.compo.edu

点击编辑:

点击删除:

直接访问 www.compo.edu/hello

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:一个框架跑起来, 挺不容易的, 里面有许多的坑要填
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!