ci4废弃ci3的$this->load->view()链式调用,改用返回字符串的view()函数;需echo显式输出或封装render_layout()辅助函数控制布局,且视图路径严格限定于app/views/。

CI4 不再支持 CI3 那种 $this->load->view() 连续调用拼接视图的方式——它直接移除了 $this->load 对象,改用函数式 view(),且默认返回字符串而非直接输出。想拼出 header/content/footer 结构,必须主动控制输出顺序和变量作用域。
为什么直接多次调用 view() 不行
CI4 的 view() 默认返回渲染后的 HTML 字符串,不会自动 echo 到响应流。如果你写:
view('header');
view('content');
view('footer');
结果是三个字符串被计算出来又丢弃,页面一片空白。常见错误现象就是「页面没内容但 HTTP 状态 200」或「只显示最后一个 view 的内容」(误以为开了 echo)。
- CI4 的
view()是纯函数,无副作用,不自动输出 - 没有全局视图堆栈或隐式输出缓冲控制
- 试图在视图里
echo $this->view('xxx')会报错:CI4 视图中不可访问$this
正确做法:用 view() + echo 显式拼接
最简可控方式,就是在控制器里手动 echo 每个片段的返回值:
echo view('layouts/header', $data);
echo view('pages/home', $data);
echo view('layouts/footer', $data);
注意点:
-
$data会透传给每个view()调用,无需重复构造 - 所有路径都是相对于
app/Views/,比如layouts/header对应app/Views/layouts/header.php - 不要在某个子视图里写
exit或redirect(),否则后续echo不执行 - 若需在 header 中动态注入 JS/CSS,建议在
$data里预留'scripts' => [],然后在layouts/header.php里循环foreach ($scripts as $s) echo '<script src="'.%20esc(%24s)%20.'"></script>';
进阶方案:封装 render_layout() 辅助函数
当项目变大、layout 类型增多(如 admin、public、minimal),硬编码 echo view() 易出错。可新建 app/Helpers/layout_helper.php:
function render_layout(string $layout, string $content_view, array $data = [])
{
$data['content_for_layout'] = view($content_view, $data);
return view("layouts/{$layout}", $data);
}
控制器中调用:
return render_layout('main', 'pages/dashboard', $data);
对应 app/Views/layouts/main.php 必须包含:
<?php echo $content_for_layout; ?>
关键约束:
- 不能在
layouts/main.php里做权限跳转或重定向——逻辑必须收口到控制器 - 该函数返回的是完整字符串,所以控制器必须用
return(而非echo)交给框架输出 - 若启用缓存,
$content_for_layout会提前渲染,无法延迟执行 content 视图里的动态逻辑
真正容易被忽略的是:CI4 的视图路径解析完全依赖文件系统,不支持 CI3 那种「模块内相对路径」;一旦用了 HMVC 扩展,子模块的视图仍得放在 app/Views/ 下,否则 view() 找不到——这不是配置问题,是设计使然。











