codeigniter 3.1.13 可通过多次 $this->load->view() 手动拼装页头、主体、页脚实现模板复用;须用第三个参数传数据,避免 load->vars() 全局污染;注意输出缓冲、路径使用 base_url() 及变量显式传递。

直接用 $this->load->view() 嵌套加载就行
CodeIgniter 3.1.13 不支持 Blade 那种 @include 语法,也没内置 layout 模板继承机制,但完全可以用多次 $this->load->view() 手动拼装页头、主体、页脚。控制器里不传参、不合并、不重写核心类,就能干净实现。
常见错误是试图在视图里直接 require 'header.php' —— 这会绕过 CI 的加载逻辑,导致辅助函数(如 base_url())、语言行、session 数据不可用,还可能触发“headers already sent”警告。
- 页头(
header.php)和页脚(footer.php)统一放在application/views/includes/下 - 主视图(如
home.php)只写业务 HTML,不包含或结构 - 控制器中按顺序调用:
$this->load->view('includes/header')→$this->load->view('home')→$this->load->view('includes/footer')
$this->load->view() 的第三个参数能传数据进公共模板
页头常需动态 title、meta、CSS 路径;页脚可能要显示版权年份或统计代码。这些不能硬编码,得靠第三个参数传数组进去。
比如在控制器里:
$data = [
'title' => '首页',
'css_files' => ['home.css'],
'year' => date('Y')
];
$this->load->view('includes/header', $data);
$this->load->view('home', $data); // 主视图也能用 $title 等
$this->load->view('includes/footer', $data);
这样 header.php 里就能安全用 <title><?php echo htmlspecialchars($title); ?></title>,不用全局变量或 $this->load->vars() 这种易冲突的方式。
避免用 $this->load->vars() 全局注入
有人图省事,在控制器开头调一次 $this->load->vars(['title' => '首页']),以为后续所有 view() 都能访问。问题在于:它对所有后续视图生效,包括页脚里你可能不想暴露的调试变量;更麻烦的是,如果多个视图重复调用 vars(),后设的会覆盖先设的,容易漏掉字段或污染作用域。
真正可控的做法只有两个:
- 每个
view()调用都显式传$data(推荐,清晰、隔离) - 把公共变量抽成独立 helper 函数,比如
get_site_title(),在视图里直接调用(适合极少变动的配置项)
注意输出顺序和缓冲区陷阱
CI 3.1.13 默认开启输出缓冲(output buffering),所以多次 view() 不会立即输出,而是攒到最后 flush。这本来是好事,但如果你在某个视图里写了 echo 'debug'; exit;,就可能卡在中间——页头已输出,但页脚没走完,HTML 不闭合,浏览器渲染异常。
调试时建议:
- 禁用缓存:在
index.php顶部加ob_end_clean();(仅开发环境) - 检查是否误调了
$this->output->set_output(),它会截断后续所有view()输出 - 页脚里别依赖前面视图的 PHP 变量状态(比如
$user_logged_in),必须显式传进来
最易被忽略的是:页头和页脚里的 JS/CSS 路径必须用 base_url(),不能写死相对路径;否则在子目录路由(如 /admin/user/edit)下会 404。这点一错,整个页面样式就崩,但错误不报在 PHP 层,排查起来反而慢。











