在PHP框架中利用模板继承构建可维护的前端视图结构

Oliver
Oliver
发布时间:2026-09-22 | 3人浏览过
原创

在PHP框架中构建前端视图时,比较容易维护的做法不是让每个页面重复写完整的 <html>、导航栏、侧边栏和页脚,而是把这些公共结构集中到一个基础布局中, 再让具体页面通过模板继承只填写自己真正不同的内容。配合局部模板和组件,可以把“页面骨架”“页面内容”和“重复模块” 分成不同层次,后续修改导航、资源引用或整体布局时不必逐页处理。

一、模板继承解决的核心问题是什么

假设一个后台系统包含用户列表、订单列表、文章管理和系统设置四个页面。它们可能都有相同的顶部导航、 左侧菜单、CSS文件、JavaScript文件和页脚,真正变化的通常只是页面标题与中间内容。

如果每个页面都保存一份完整HTML结构,就会产生大量重复代码。导航增加一个菜单时需要修改多个文件, CSS或JavaScript引用发生变化时也容易遗漏某些页面。

模板继承的思路是把页面分成几个层次:

  • 基础布局:负责HTML骨架、公共资源、导航、侧栏和页脚。
  • 内容区块:由不同页面覆盖,例如页面标题、主体内容和额外脚本。
  • 局部模板或组件:负责表格、分页、提示框、表单字段等重复出现的小结构。
在PHP框架中利用模板继承构建可维护的前端视图结构
图1:基础布局定义整体骨架,各业务页面只覆盖需要变化的区块,共用的小模块继续拆成局部模板或组件。

二、先建立一个稳定的基础布局

模板继承的第一步不是马上拆很多组件,而是找到多个页面真正共有的部分。一般可以从HTML文档结构、 CSS资源、顶部导航、侧栏、主体容器和JavaScript资源开始。

不同PHP框架的模板语法不完全相同,但通常都存在类似“继承布局”“定义区块”“输出区块”的能力。 下面使用接近常见PHP模板引擎的伪代码说明结构,具体项目中可以换成框架实际提供的 extends、section、block、yield 等指令。

例如建立一个基础布局文件:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>@yield('title', '管理后台')</title>
    <link rel="stylesheet" href="https://www.ipython.cn/assets/app.css">

    @yield('styles')
</head>
<body>

    @include('partials.header')

    <div class="app-layout">
        @include('partials.sidebar')

        <main class="main-content">
            @yield('content')
        </main>
    </div>

    @include('partials.footer')

    <script src="https://www.ipython.cn/assets/app.js"></script>
    @yield('scripts')
</body>
</html>

这里真正值得注意的不是指令名称,而是结构划分: header、sidebar 和 footer 属于公共区域, content 是每个页面最主要的变化区域,而 styles 与 scripts 则为少数页面留下扩展入口。

不要因为模板引擎支持区块,就为每一个HTML标签建立一个区块。区块应该对应“页面真正需要覆盖的变化点”, 否则基础模板会出现大量零散插槽,反而增加理解成本。

三、让业务页面只描述自己的内容

基础布局建立后,用户列表页不再负责输出完整HTML文档,而是继承公共布局并填写自己的页面标题和主体内容。

@extends('layouts.admin')

@section('title', '用户管理')

@section('content')
    <div class="page-header">
        <h1>用户管理</h1>
        <a href="/users/create" class="button">新增用户</a>
    </div>

    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>用户名</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            @foreach ($users as $user)
                <tr>
                    <td>{{ $user->id }}</td>
                    <td>{{ $user->name }}</td>
                    <td>{{ $user->email }}</td>
                    <td>
                        <a href="/users/{{ $user->id }}/edit">编辑</a>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
@endsection

页面文件现在只包含“这个页面与其他页面有什么不同”。如果以后整个后台的侧栏宽度、导航结构或公共脚本发生变化, 主要修改基础布局及对应局部模板即可,业务页面不需要重复调整。

在PHP框架中利用模板继承构建可维护的前端视图结构
图2:从现有重复页面重构为模板继承结构时,可以按照公共结构识别、布局建立、页面继承、组件拆分和验证的顺序进行。

四、不要把模板继承和局部模板混成一件事

模板继承和局部模板都可以减少重复代码,但解决的问题不同。理解这一点之后,视图目录通常会清楚很多。

模板继承处理的是纵向层级关系。例如后台所有页面都建立在同一个管理后台骨架上, 用户页面继承后台布局,订单页面也继承后台布局。

局部模板处理的是横向复用关系。例如用户页和订单页都需要分页条, 这时分页并不适合成为整个页面的父模板,而更适合作为一个可以被不同页面包含的独立模块。

需求 更适合的方式 原因
多个后台页面共享导航、侧栏和页脚 模板继承 这些内容构成稳定的页面骨架,存在明确父子关系。
多个页面都需要同一个分页结构 局部模板或组件 分页只是页面中的一个小模块,不决定整个页面结构。
普通后台页与登录页结构完全不同 分别建立布局 强行共用同一个布局会产生大量条件判断。
某个页面需要额外加载编辑器脚本 扩展脚本区块 公共脚本仍由父布局管理,只为特殊页面增加附加资源。

五、为什么简单 include 拼装和模板继承维护起来不同

PHP项目也可以通过多个 include 把头部、菜单和页脚拼起来。对于页面数量很少、 结构也很简单的项目,这种方式并非不能使用。

差别主要出现在页面结构开始复杂以后。简单的 include 更像是“当前页面主动把几个文件拼进来”, 模板继承则是“父布局规定整体结构,子页面只提供指定内容”。后者的页面结构约束通常更明确。

在PHP框架中利用模板继承构建可维护的前端视图结构
图3:include 主要解决文件复用,模板继承进一步明确了父布局与子页面的结构关系,两者也可以在同一项目中配合使用。

两者不是必须二选一。一个常见而清晰的组合就是: 用模板继承控制页面级结构,用 include 或组件复用页面中的小模块。

六、为不同类型的页面建立合适的布局层级

模板继承并不意味着整个项目只能有一个基础布局。一个网站经常同时存在前台、管理后台和登录认证页面, 它们的结构可能明显不同。

例如可以采用这样的目录:

views/
├── layouts/
│   ├── app.php
│   ├── admin.php
│   └── auth.php
│
├── partials/
│   ├── header.php
│   ├── footer.php
│   ├── sidebar.php
│   └── pagination.php
│
├── users/
│   ├── index.php
│   ├── create.php
│   └── edit.php
│
├── orders/
│   ├── index.php
│   └── show.php
│
└── auth/
    ├── login.php
    └── register.php

这里的 app.php 可以作为网站前台布局,admin.php 负责管理后台, auth.php 则用于登录、注册等不需要后台侧栏的页面。

这样比在一个超级布局里不断写 if ($isLoginPage)、if ($showSidebar)、 if ($isAdmin) 更容易维护。条件判断不是完全不能出现,而是不应该用大量条件去掩盖实际上已经不同的页面结构。

七、只在需要时给页面增加专属CSS和JavaScript

一个常见问题是:公共布局已经统一加载CSS和JavaScript,但某个编辑页面还需要富文本编辑器或图表库, 难道要把这些资源加载到所有页面吗?

更合适的方式是在基础布局中保留额外资源区块。

<head>
    <link rel="stylesheet" href="https://www.ipython.cn/assets/app.css">
    @yield('styles')
</head>

...

<script src="https://www.ipython.cn/assets/app.js"></script>
@yield('scripts')

需要额外脚本的页面再单独填写:

@section('scripts')
    <script src="https://www.ipython.cn/assets/editor.js"></script>
    <script>
        initEditor('#content');
    </script>
@endsection

普通页面不会因此加载 editor.js,而编辑页面仍然沿用同一个基础布局。 这就是模板区块比较合适的使用场景:整体结构保持一致,但允许少量、明确的页面差异。

八、模板中尽量不要塞入业务逻辑

模板继承解决的是视图结构问题,并不意味着所有代码都应该搬进模板。控制器、服务层和模板之间仍然需要保持职责边界。

例如用户状态文字最好在进入视图之前已经形成容易使用的数据,而不是在模板里不断处理复杂判断:

<!-- 不建议让模板承担过多业务判断 -->
@if ($user->status === 1 && $user->expired_at > time() && ...)
    ...
@endif

模板中的条件判断适合控制“是否显示某个区域”“当前列表是否为空”之类的展示逻辑。 如果判断已经涉及复杂业务规则,应尽量在控制器、服务或专门的视图数据转换层中处理。

这样做与模板继承的目标是一致的:让视图文件尽可能只回答“页面应该怎样展示”,而不是同时负责大量业务计算。

九、常见的几个维护问题

1. 基础布局越来越大

如果导航、用户菜单、消息中心、侧栏和页脚全部直接堆在布局文件中,布局本身仍然会变得难读。 可以继续把稳定的独立区域拆成局部模板:

@include('partials.header')
@include('partials.sidebar')
@include('partials.footer')

基础布局负责确定这些区域出现在哪里,而局部模板负责各自区域内部的HTML。

2. 页面继承层级太深

理论上可以设计多层继承,例如基础布局 → 后台布局 → 内容管理布局 → 文章编辑布局。 但层级过深后,开发者很难快速判断某段HTML到底由哪个模板输出。

如果只是为了复用一个小区域,通常更适合拆成组件或局部模板,而不是继续增加继承层级。

3. 为每个小差异建立区块

一个布局如果出现几十个可覆盖区块,意味着父布局已经很难定义稳定结构。 比较合适的区块通常是标题、主要内容、头部扩展资源、底部扩展脚本,以及少数确实需要覆盖的大区域。

4. 把所有页面强行放进同一个布局

登录页、打印页、错误页和后台工作台可能有完全不同的页面结构。如果为了共享一个父模板而加入大量条件, 建立第二个布局往往会更直观。

十、如何判断当前视图结构是否已经比较合理

完成模板继承改造后,可以从实际维护动作反过来检查结构,而不是只看目录是否整齐。

  • 修改顶部导航时,是否只需要修改一个主要位置?
  • 新增普通后台页面时,是否只需要编写这个页面自己的正文?
  • 修改公共CSS或JavaScript入口时,是否不需要逐个页面修改?
  • 重复出现的分页、提示框或表单模块,是否已经形成独立可复用结构?
  • 登录页等特殊页面是否能够使用自己的布局,而不是依赖大量条件判断?
  • 阅读一个业务页面时,能否很快看出它真正负责什么内容?
在PHP框架中利用模板继承构建可维护的前端视图结构
图4:最终结构并不是追求模板数量越少越好,而是让布局、业务页面、复用模块和业务逻辑各自承担清晰职责。

十一、一个完整的视图组织思路

把前面的做法组合起来,一个比较清晰的PHP框架视图结构可以这样理解:

  1. 先识别多个页面真正共有的HTML骨架。
  2. 把公共骨架放入基础布局,并预留少量明确的内容区块。
  3. 业务页面继承布局,只输出页面标题、正文和必要的专属资源。
  4. 分页、提示框、表单字段等重复模块再拆成局部模板或组件。
  5. 前台、后台、登录等结构差异较大的页面使用不同布局。
  6. 避免为了复用少量HTML建立过深的继承关系。
  7. 复杂业务判断放到控制器、服务或数据转换层,模板主要负责展示。
总结: 模板继承真正带来的价值不是少写几个HTML标签,而是建立清楚的视图层次。 基础布局负责稳定骨架,业务页面负责差异内容,局部模板和组件负责重复模块。 当公共结构发生变化时,可以在较少的位置完成修改;当增加新页面时,也不需要再次复制整套HTML。 对PHP框架项目来说,这种结构比单纯追求“把代码拆成很多文件”更重要,因为每个文件为什么存在、应该负责什么,都有明确边界。
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表