CodeIgniter 4 多应用共存需人工隔离路由作用域,否则引发 URL 冲突、误调用或越权访问;应据子目录、子域名等部署结构选用 URI 前缀、路由分组或 HTTP_HOST 动态加载策略。

多个 CodeIgniter 4 应用共存于同一服务器(如通过子目录或子域名部署)时,若共用同一份 app/Config/Routes.php 或未隔离路由作用域,会导致 URL 映射冲突、控制器误调用、甚至 404 或越权访问——比如子应用 /admin/login 被主应用的路由规则捕获并转发到错误控制器。
确认路由作用域边界
CodeIgniter 4 的路由系统默认全局生效,【所有 $routes->get()、$routes->post() 等注册的路由都会被框架统一匹配】,不存在天然的应用级隔离。因此必须人为划定作用域:要么物理分离配置文件,要么逻辑分组约束匹配条件。
检查当前部署结构是否属于以下任一情形:子目录部署(如 https://example.com/app1/ 和 https://example.com/app2/)、子域名部署(如 app1.example.com 和 app2.example.com)、或同一入口但不同命名空间前缀(如 /api/v1/xxx vs /panel/xxx)。不同结构对应不同隔离策略。
子目录部署:用 URI 前缀硬性过滤
方法一:在每个应用的 app/Config/Routes.php 中,所有路由 URI 显式加上该应用专属前缀
打开 app1/app/Config/Routes.php,将原本的 $routes->get('/login', 'Auth::login'); 改为:
$routes->get('/app1/login', 'Auth::login');
同理,在 app2/app/Config/Routes.php 中全部使用 /app2/xxx 开头的 URI。这是最直接、零依赖的方式,但要求前端链接和重定向地址也同步改写为带前缀路径。
方法二:启用路由分组 + 前置匹配条件(推荐)
在 app1/app/Config/Routes.php 开头添加:
$routes->group('app1', function ($routes) {<br> $routes->get('/login', 'Auth::login');<br> $routes->get('/dashboard', 'Dashboard::index');<br>});
此时框架会自动将所有组内路由注册为 /app1/login、/app1/dashboard。注意:【group 第一个参数是 URI 前缀,不是目录名,且不能含斜杠开头】,写成 '/app1' 会报错。
子域名部署:按 HTTP_HOST 动态切换路由表
第一步:在 app/Config/Routes.php 顶部获取当前域名
$host = $_SERVER['HTTP_HOST'] ?? '';
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
第二步:用 if 分支加载不同路由配置
if (strpos($host, 'admin.') === 0) {<br> require APPPATH . 'Config/RoutesAdmin.php';<br>} elseif (strpos($host, 'api.') === 0) {<br> require APPPATH . 'Config/RoutesApi.php';<br>} else {<br> // 主站路由<br> $routes->get('/', 'Home::index');<br>}
第三步:把各子应用的路由逻辑拆到独立文件,如 app/Config/RoutesAdmin.php,内容只含 $routes->get(...) 等语句,不包含 <?php 开头或命名空间声明——因为它是被 require 进来的上下文。
这一步必须确保 Web 服务器(Apache/Nginx)已正确将子域名解析到对应应用的 public/ 目录,否则 $_SERVER['HTTP_HOST'] 获取值为空或错误。
同一入口多命名空间:用命名空间前缀隔离控制器调用
第一步:为不同应用定义专属命名空间
在 app/Controllers/Admin/ 下放后台控制器,在 app/Controllers/Api/ 下放 API 控制器,两者类名可同为 Users,但完整命名空间分别为 App\Controllers\Admin\Users 和 App\Controllers\Api\Users。
第二步:路由注册时显式写出完整命名空间
$routes->get('/admin/users', 'App\Controllers\Admin\Users::index');
$routes->get('/api/users', 'App\Controllers\Api\Users::index');
这样即使两个控制器方法名完全一致,也不会互相覆盖。CI4 路由匹配的是字符串形式的控制器路径,不是类名本身。
第三步:禁止跨命名空间自动解析(关键)
打开 app/Config/Routes.php,确认未启用 $routes->setAutoRoute(true)。一旦开启,框架会尝试根据 URI 自动推导控制器,极易导致 /api/users 被错误映射到 App\Controllers\Users 而非 App\Controllers\Api\Users。


















