用二级域名绑定CI框架的各个模块,核心方法是在入口文件或路由中解析域名前缀,再将请求分发到对应模块目录,不需要安装额外插件。这套方案既能保持模块隔离又便于维护,下面从原理到实操逐步展开。
为什么要用二级域名做CI框架多模块开发
CI框架默认的模块划分是单入口加分段式URL,yourdomain.com/index.php/admin/user 这样访问后台,但业务复杂后,前台、后台、API、商家中心混在一个域名下,路由规则会迅速膨胀,权限控制也容易出漏洞,行业共识认为,用二级域名做物理隔离是最省心的模块化方案。
- 前台绑定
www.yourdomain.com,对应前台模块 - 后台绑定
admin.yourdomain.com,对应后台模块 - 接口绑定
api.yourdomain.com,对应接口模块
站点规模达到一定程度后,二级域名方案比路由前缀方案的维护成本低很多,比如API模块要单独配置HTTPS证书、或部署到独立服务器时,二级域名天然支持这些操作,不需要大改应用代码。
CI框架多模块开发配置的目录结构规划
先搞懂CI框架的模块路由原理
CI框架本身默认不支持多模块,它的一级目录对应的是控制器,不是模块,要实现多模块开发,业内普遍做法是在 application 目录下手工创建模块目录,再通过路由或入口文件切换。
典型目录结构:
application/
├── controllers/
│ ├── front/ // 前台模块
│ ├── admin/ // 后台模块
│ └── api/ // 接口模块
├── models/
│ ├── front/
│ ├── admin/
│ └── api/
└── views/
├── front/
├── admin/
└── api/
这种按模块分层的目录结构,配合二级域名绑定,逻辑清晰,关键是控制器里的类名要带模块前缀,Front_user、Admin_user,避免不同模块出现同名控制器导致加载冲突。
CI框架二级域名具体配置步骤
第一步:配置服务器二级域名解析
确保每个模块的二级域名都解析到同一台服务器,以Nginx为例:

server {
server_name admin.yourdomain.com;
root /var/www/yourapp;
index index.php;
location ~ .php$ {
fastcgi_param CI_ENV 'production';
}
}
Apache则需要在 httpd.conf 添加虚拟主机,并把每个域名的根目录指向同一个项目入口,这里容易踩坑的是部分服务器默认拒绝访问 .htaccess,需要在虚拟主机里加 AllowOverride All。
第二步:修改CI框架入口文件
在根目录的 index.php 中,根据当前域名设置模块标识:
$domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
$module = 'front'; // 默认前台
if (strpos($domain, 'admin.') === 0) {
$module = 'admin';
} elseif (strpos($domain, 'api.') === 0) {
$module = 'api';
}
define('MODULE_NAME', $module);
这样框架启动时就能识别当前所属模块,后续控制器加载和视图路径也都以这个常量为基础,实际上你也可以用 getenv 或配置文件来做映射,但直接解析HTTP_HOST是最直观的方式。
第三步:设置路由规则实现模块分发
在 application/config/routes.php 中,结合上面的 MODULE_NAME 常量做默认路由:
// 明确指定模块目录 $route['default_controller'] = MODULE_NAME . '/login'; $route['404_override'] = MODULE_NAME . '/not_found';
访问 admin.yourdomain.com/user/lists 时,控制器加载路径就是 application/controllers/admin/user.php,类定义为:
class User extends CI_Controller {
public function lists() {
$this->load->view('admin/user_list');
}
}
将模块名作为子目录放进去,CI框架会自然匹配,同理模型和视图也需要加上模块子目录的引用路径,$this->load->model('admin/user_model'),视图用 $this->load->view('admin/user_list')。
第四步:处理公共资源路径和跨模块跳转
多模块场景下,CSS、JS、图片这些静态资源建议放在根目录的

assets 文件夹,统一用绝对路径引用,避免相对路径在不同域名下失效,跨模块跳转则需要注意域名切换,例如后台登录成功后跳转到前台个人中心,URL要拼接完整的二级域名,不能直接写相对路径。
举例说明,后台跳转前台的封装方法:
$url = 'http://www.yourdomain.com/user/profile'; redirect($url);
这个方法在本地开发环境和线上环境略有差异,本地测试时建议临时修改本机 hosts 文件,把所有二级域名指向 0.0.1,否则无法通过域名切换来验证。
CI框架模块开发二级域名配置常见问题
伪静态规则导致子模块404
很多人在Nginx下配置了CI框架的伪静态后,发现二级域名访问后台出现404,原因就是把重写规则应用到了所有server块,Nginx伪静态配置应为:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
每个server块单独配置,不要共用一套规则,Apache环境下检查 .htaccess 的 RewriteBase 是否继承了域名的目录路径,多个虚拟主机共用项目根目录时需要注释掉 RewriteBase。
二级域名下session跨域失效
后台和前台分布在两个二级域名下,如果共用session做登录态同步,默认的COOKIE配置会导致session丢失,解决办法是在 config.php 中设置COOKIE域名为顶级域名:
$config['cookie_domain'] = '.yourdomain.com';
设置后,所有子域名共享Cookie,但注意访问HTTPS证书的域名,Cookie的Secure属性要改为使用合适的值,否则在HTTP下请求会携带不了COOKIE。
CI框架版本差异带来的兼容问题
CI 3.x和CI 4.x在多模块配置上有差异,CI 4.x推荐用命名空间方式绑定模块路径,打开 app/Config/Routes.php,以数组方式定义模块的命名空间对应关系,比CI 3.x里纯粹靠目录前缀更灵活,如果你的项目需要长期维护和二次开发,建议优先选择CI 4.x,其多模块配置方式更贴近现代PHP框架的习惯,后续升级成本更低。

用二级域名做CI框架多模块的实际场景扩展
后台模块部署好后,如果还想细分页面,seller.yourdomain.com 给商家、 user.yourdomain.com 给普通用户,只需要在同一条规则上增加域名前缀判断即可,入口文件里的映射关系加一行代码的事。
大型项目后期做微服务拆分时,二级域名方案的优势会更明显先把模块独立出来,再逐步将API层拆成单独服务,数据库、缓存等独立部署,不需要改变CI框架的调用方式,这是一条平滑演进的道路,项目增长空间足够大时特别适用,但如果是只有一个后台加几个页面的小项目,直接用路由前缀就行,没必要为了用二级域名而用二级域名,反而增加部署复杂度。
常见问题问答
CI框架配置二级域名后,数百万级的访问量会不会有性能瓶颈?
二级域名本身不产生性能开销,入口文件多几行域名判断的代码几乎可以忽略不计,真正的瓶颈在于CI框架单入口的结构,所有请求都经过同一个 index.php,高并发下PHP进程数会成为限制因素,建议配合OPcache和PHP-FPM调优,必要时对API模块单独部署到独立Nginx节点,避免互相挤占资源。
多个二级域名共用一套CI框架,代码升级时怎么降低风险?
推荐按模块拆分git仓库,每个模块独立发版,使用部署工具同步到服务器上子模块对应的目录即可,即使某个模块出错,其他域名不受影响,部署后先在测试域名验证一遍,再切换生产域名的软链接。
原有路由模式下已有大量URL,迁移到二级域名会不会破坏外链?
确实会有影响,搜索引擎已经收录了旧的 /admin/user 这种URL,换成 admin.yourdomain.com/user 后,需要逐个做301跳转,迁移前用 routes.php 写一个全局规则,把旧路径统一重定向到新域名对应页面,并在robots中提交新的sitemap,等搜索引擎重新收录后逐步移除跳转规则,二级域名的最终效果是一个可独立部署、权限清晰、扩展性强的多模块架构,而且CI框架的配置方式在多个项目间完全可复用。