博客列表 >用composer搭建简单框架

用composer搭建简单框架

Yang_Sir
Yang_Sir原创
2020年05月20日 18:07:341258浏览
  • 这是一个简单的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

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议