
本文介绍在经典 MVC 结构中,如何通过控制器统一传递页面标识(如 'home' 或 'contact')至共享 Header 模板,并在 或其他位置动态渲染,避免重复代码,提升可维护性。
本文介绍在经典 mvc 结构中,如何通过控制器统一传递页面标识(如 'home' 或 'contact')至共享 header 模板,并在 `
在典型的 PHP MVC 应用中,Header(如 区域)通常被抽离为独立的 header.php 文件,并通过 require_once 在多个视图中复用。但若每个页面需显示不同的标题(如“首页”“联系我们”),直接硬编码无法满足需求——必须将动态数据从当前页面“透传”至 Header。
核心思路:不调用模型方法返回值,而是由控制器统一注入数据
你当前尝试在视图中直接调用 model::nametag('homepage') 是不可取的:
- 静态方法调用无法持久保存状态;
- Header 在视图加载前已渲染,单独调用函数无法影响其输出;
- 违背 MVC 数据流规范(数据应由 Controller 准备,View 负责展示)。
✅ 正确做法是:Controller 在渲染视图前,将页面名称作为 $data 参数传入 view() 方法,并在 Header 中使用该变量。
✅ 步骤实现
-
修改 Controller 的
view()方法,确保$data可被 Header 访问
当前你的view()已支持$data=[],但需确保它在引入header.php前已 extract(解包)为局部变量:function view($viewurl, $data = [], $noincludeheader = '', $noincludefooter = '') { // 将$data中的键值转为变量(如 ['page_title' => '首页'] → $page_title = '首页') extract($data); if ($noincludeheader == '') { require_once('views/share-base/header.php'); // 此时 $page_title 已可用 } require_once('views/' . $viewurl . '.php'); if ($noincludefooter == '') { require_once('views/share-base/footer.php'); } } -
在具体页面控制器中调用
view()并传入页面标识
例如HomeController.php:class HomeController extends Controller { public function index() { $this->view('index', ['page_title' => '首页', 'meta_keywords' => 'PHP,MVC,首页']); } } -
在
header.php中安全使用变量<base href="<?=%20URL%20?>"><meta charset="utf-8"><title>= htmlspecialchars($page_title ?? '默认标题') ?></title><?php if (isset($meta_keywords)): ?><meta name="keywords" content="<?= htmlspecialchars($meta_keywords) ?>"><?php endif; ?>
⚠️ 注意事项:
- 始终对输出到 HTML 的变量使用
htmlspecialchars()防止 XSS;- 使用
??运算符提供默认值,避免未定义变量警告;- 不要在视图中直接调用模型静态方法传递状态——模型应专注业务逻辑,而非控制渲染流程;
- 若需全局 SEO 数据(如 title + description + keywords),建议封装为
SeoHelper类,在 Controller 中实例化并注入。
总结
动态页面标题的本质是 数据驱动渲染,而非函数调用。MVC 的职责分离要求 Controller 承担“准备数据”的角色,View(包括 Header)只负责“展示数据”。通过 extract($data) 机制,即可让共享 Header 无缝获取任意页面专属信息,既简洁又符合架构规范。










