ci3适合老旧环境单人项目,ci4必须用于现代团队开发;ci4需composer安装且web根目录为public/;控制器须声明命名空间并继承controller;数据库操作禁用字符串拼接防sql注入;filters需手动挂载到路由才生效。

选错CodeIgniter版本会导致项目中途重构、团队协作卡壳、甚至上线后频繁报错——CI3和CI4不是简单“新旧”关系,而是两套完全不同的运行逻辑和开发范式。
先看你的项目类型和团队现状
如果项目是内部管理后台、单人维护、PHP版本≤7.4、服务器配置老旧(比如共享主机)、且已有CI3代码可复用,【CI3是更稳妥的选择】。它没有Composer强依赖,解压就能跑,路由写法直白,社区教程满天飞,查错快。
如果项目要长期迭代、团队≥2人、PHP版本≥8.0、需要对接现代前端框架(Vue/React)、或计划未来接入JWT、队列、API限流等扩展能力,【必须选CI4】——CI3的类自动加载机制、Session锁缺陷、无命名空间支持,在PHP 8.1+下已出现兼容性告警,部分插件(如Datatables)在CI3里根本跑不起来。
CI4安装必须走Composer,且Web根目录只能设在public/
第一步:执行命令 composer create-project codeigniter4/appstarter myproject,不要下载zip包手动解压。
第二步:Apache或Nginx的DocumentRoot必须指向 myproject/public/,不是 myproject/。否则访问首页会直接报Whoops!错误,这不是代码问题,是路径暴露了app/和system/目录。
第三步:检查index.php是否被删改过——CI4的public/index.php是唯一入口,不能挪动、不能重命名、不能复制到其他目录。删掉它整个应用就瘫痪。
控制器写法差异:CI3能抄,CI4一抄就崩
方法一:CI3控制器示例(可直接运行)
class Home extends CI_Controller { public function index() { $this->load->view('welcome_message'); } }
方法二:CI4控制器正确写法(缺任何一行都报错)
namespace AppControllers;
use CodeIgniterController;
class Home extends Controller
{
public function index()
{
return view('welcome_message');
}
}
注意:CI4控制器必须声明namespace;必须继承Controller而非CI_Controller;返回视图用return view(),不是$this->load->view();漏写namespace或错写成App\Controllers会导致Class not found。
数据库操作别混用,否则SQL注入风险藏得极深
第一步:CI4中禁止写这种代码:$this->db->query("SELECT * FROM users WHERE id = {$id}");——变量直接拼接,CI4不做自动转义,【这就是明文SQL注入通道】。
第二步:正确写法只有两种:
① 绑定参数:$this->db->query("SELECT * FROM users WHERE id = ?", [$id]);
② 查询构建器:$this->db->where('id', $id)->get('users');
第三步:复杂查询(含JOIN、子查询)必须用Query Builder链式调用,手写SQL字符串必须配合参数绑定,否则CI4的防注入机制不生效。
CI4的Filters必须手动挂载到路由,否则形同虚设
第一步:在app/Config/Filters.php中定义过滤器类,比如LoginFilter。
第二步:在app/Config/Routes.php中显式绑定:$routes->add('admin/*', 'Admin::index', ['filter' => 'login']); 或 $routes->group('admin', ['filter' => 'login'], function($routes) { ... });
第三步:不绑定到具体路由组或单个路由,Filter就永远不会触发——它不像Laravel中间件那样全局默认启用,【没挂载=没存在】。











