codeigniter视图中应使用$this->load->view()加载子视图,不可用include/require;不支持返回字符串;变量需显式传递;业务逻辑(如查库)应由控制器处理,避免在视图中加载模型或执行数据库操作。

视图里直接用 $this->load->view() 就行
CodeIgniter 不支持 PHP 原生 include 或 require 加载视图文件,因为视图不是普通 PHP 文件——它运行在 CI 的上下文里,依赖 $this(即控制器实例)和已加载的辅助函数、语言项等。强行 include('side.php') 会报 Fatal error: Using $this when not in object context。
正确做法是在视图中调用 $this->load->view(),和控制器里写法完全一致:
<?php $this->load->view('side'); ?>
- 路径按
application/views/为根,支持子目录,比如$this->load->view('partials/nav')对应application/views/partials/nav.php - 可以传数据,如
$this->load->view('side', ['title' => '侧栏标题']),这些变量在side.php中直接可用 - 不支持返回字符串(即不能像控制器里那样传第三个参数
true),视图里调用$this->load->view()总是直接输出
为什么不能在视图里用 get_instance() 手动取模型或库
有人试过在 side.php 里写 $CI =& get_instance(); $CI->load->model('menu_model'); —— 理论上可行,但极不推荐。
问题在于:模型一旦在视图中加载,就绑定到当前请求生命周期的单例 CI_Loader 实例;如果多个视图片段都各自加载同名模型(比如都加载 menu_model),第二次加载会静默失败(CI 默认不重复加载),且容易掩盖逻辑耦合问题。
- 模型该由控制器统一加载并准备好数据,再通过
$data传给视图或子视图 - 如果
side.php需要动态菜单数据,应在控制器里查好、塞进$data['menu_items'],再传给主视图,主视图再透传给side - 硬要在视图里调模型,等于把业务逻辑下沉到展示层,调试和复用成本陡增
$this->load->view() 在视图中嵌套调用的限制
CI 允许视图里再加载视图,但要注意执行顺序和变量作用域。
比如 welcome.php 中写了:
访问全球海洋潮汐模型。功能包括查询指定日期、时间和地点的潮高、潮汐极值及格点天气数据。
<?php $title = '首页'; ?><?php $this->load->view('header'); ?>
<h1><?php echo $title; ?></h1>
<?php $this->load->view('footer'); ?>
这时 header.php 和 footer.php 是能访问 $title 的(PHP 变量作用域使然),但它们**无法访问控制器传来的原始 $data 数组里的键**,除非你显式重传:
- 错误写法:
$this->load->view('header')→header.php里用$string会报 undefined - 正确写法:
$this->load->view('header', $data)→ 所有变量原样可用 - 更稳妥的做法:主视图只传子视图真正需要的字段,比如
$this->load->view('header', ['title' => $data['title']])
想复用带逻辑的视图片段?优先封装成独立控制器方法 + AJAX
如果某个“片段”每次都要查数据库、做权限判断、甚至带表单提交,说明它已经超出纯展示范畴。硬塞进视图会导致:
- 页面首次加载变慢(所有片段同步渲染)
- 无法单独缓存该区域(CI 的页面级缓存或视图缓存都难精准控制)
- SEO 不友好(内容混在 JS 渲染后才出现)
更合理的解法是:把它拆成一个独立的控制器方法,返回 JSON 或小段 HTML,前端用 fetch 或 $.get() 加载:
class Sidebar extends CI_Controller {
public function menu() {
$this->load->model('menu_model');
$data['items'] = $this->menu_model->for_current_user();
echo $this->load->view('sidebar/menu', $data, true);
}
}
然后在主视图里留个容器:<div id="sidebar-menu"></div>,再加一行 JS 加载它。这样逻辑清晰、可测、可缓存,也避免了视图膨胀失控。
真正容易被忽略的是:视图嵌套不是万能胶,它适合静态结构复用(比如固定 header/footer),一旦开始往里塞 if($user->is_admin) 或 $this->db->query(),就该停下来想想——这还是视图该干的事吗?










