2.1 目录结构与 MVC 分工


2.1 目录结构与 MVC 分工

本节摘要:Laravel 的目录就是工地的分区规划:app 是业务车间,routes 是进件登记簿,resources 是装修材料库,database 是地基图纸柜。本节逐区讲清各目录职责与 MVC 三层(模型、视图、控制器)的分工逻辑,并用一个"查询工单详情"的最小示例,把路由、控制器、模型、视图四件套串成一条可运行的线。

从"找东西"说起

上一章把环境跑通后,你可能打开过项目根目录,被十几个文件夹糊了一脸。这一节的目标是让你看完就能"报得出位置":改页面去哪、改接口去哪、建表去哪。框架的目录约定不是强迫症,而是把"东西放哪"这个团队里最常见的沟通成本降到零——任何人接手,位置都一样。

工地分区速查

分区 里面是什么 你最常干的事
app/ 业务代码核心车间:Http 控制器、Models 模型、Providers 提供者 绝大多数业务逻辑写在这里
routes/ 路由登记簿:web.php 页面路由、console.php 命令注册 注册每个入口
resources/views Blade 装修材料库 写页面模板
database/ migrations 地基图纸、seeders 填充、factories 假数据厂 建表改表、造测试数据
config/ 全部配置文件,一行一项 改队列、数据库、缓存等配置
bootstrap/ 应用装配入口(Laravel 11 的中间件、异常、路由配置都在这) 配全局中间件与异常
public/ 唯一对外公开的目录,index.php 是所有请求的大门 Web 服务器指向这里
storage/ 运行时杂物间:日志、编译后的模板、缓存、上传文件 排查日志、清缓存
tests/ 验收检测台:Feature 与 Unit 测试 第九章的主场

MVC 的分工逻辑放工地上说最直白:控制器是工头,接路由派来的单,指挥但不亲自砌墙;模型是施工队,管数据这栋楼的进出与规矩;视图是装修队,把数据装成用户看得见的页面。工头不碰水泥,装修队不画图纸——层与层之间只通过明确接口传递材料,这就是 MVC 的全部精神。

图 2-1:目录分区与请求走向标注图

图 2-1:目录分区与请求走向标注图

动手演练:把四件套串起来

光看地图记不住,我们给第一章提到的小项目加一个"工单详情页",一次用到四件套。先登记路由:

<?php // routes/web.php use App\Http\Controllers\WorkOrderController; use Illuminate\Support\Facades\Route; Route::get('/orders/{id}', [WorkOrderController::class, 'show']) ->name('orders.show');

控制器(工头)接单,调用施工队并整理交付物:

<?php // app/Http/Controllers/WorkOrderController.php namespace App\Http\Controllers; use App\Models\WorkOrder; class WorkOrderController extends Controller { public function show(int $id) { // 工头不亲自查库,喊施工队来 $order = WorkOrder::findOrFail($id); // 把材料递给装修队渲染 return view('orders.show', ['order' => $order]); } }

模型(施工队)声明自己和哪张表、哪些字段打交道:

<?php // app/Models/WorkOrder.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class WorkOrder extends Model { // 约定优先:类名 WorkOrder 默认对应 work_orders 表 protected $fillable = ['title', 'status', 'budget']; }

视图(装修队)把数据装成页面:

{{-- resources/views/orders/show.blade.php --}} <!DOCTYPE html> <html lang="zh"> <head><meta charset="utf-8"><title>工单详情</title></head> <body> <h1>工单 {{ $order->id }}:{{ $order->title }}</h1> <p>状态:{{ $order->status }} 预算:{{ $order->budget }} 元</p> </body> </html>

访问 orders 路径加一个存在的编号,页面就出来了。注意这条链路里没有人写"去哪找类":WorkOrderController 由路由文件 use 进来,WorkOrder 由 PSR-4 自动加载按命名空间定位——这就是第一章讲过的约定在起作用。

💡 关键直觉:查无此单时 findOrFail 会直接抛出 404 异常而不是返回 null。让异常替你做兜底,比在每个控制器里手写 if 判断干净得多。这个特性在第四章验证一节还会反复用到。

新手最容易迷路的三个地方

  • 改了配置不生效:多数配置被缓存过,跑 php artisan config:clear 再看;环境相关配置永远改 .env 而不是 config 文件本身。
  • 模型找不到:命名空间必须与目录一致(App\Models 对应 app/Models),新模型建完记得 dump-autoload 不是必须的,但目录放错一定是错的。
  • 视图不渲染:blade 文件名与 view() 参数按点号对应,orders.show 对应 orders/show.blade.php,目录层级就是点号层级。

本节要点回顾

  • 分区即约定:app 车间、routes 登记簿、resources 材料库、database 图纸柜,位置说得出,代码找得到。
  • MVC 分工:工头控制器只调度,施工队模型只管数据,装修队视图只管呈现,层间只传材料不越权。
  • 四件套链路:路由登记、控制器派工、模型施工、视图装修,本节的最小示例就是全册主线的一次预演。

下一节我们打开这台工地的物资调度中心——服务容器。你会明白上面例子里 Request、模型这些依赖到底是谁送进来的。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U