CodeIgniter(简称CI)是一款轻量级的PHP框架,因为部署简单、上手快,在国内仍有大量项目在使用。当一个项目需要绑定多个域名时,比如主站是www.ipipp.com,移动端是m.ipipp.com,或者正式环境和测试环境各用一个域名,很多刚接触CI的人会不知道从哪里下手。其实CI框架本身的设计就支持灵活的配置覆盖,多域名场景完全可以基于原生的配置机制来实现,不需要修改核心代码。

一、为什么需要多域名,以及多域名的常见场景
先说清楚需求,才能选对方案。多域名在CI项目中大致有三种典型用法。第一种是多端分离:PC站和手机站内容同源但模板不同,分别用www和m两个域名访问,代码只部署一份,通过域名判断加载不同的视图目录。第二种是多站点共用框架:一台服务器跑几个小站,每个站点一个域名,共享CI的核心类库和公共函数,各自有独立的控制器和配置。第三种是环境区分:开发、测试、生产环境分别绑定不同的域名,CI根据当前域名自动加载对应的数据库配置,避免上线时手动改配置文件出错。
这三种场景的技术实现有重叠也有区别。核心问题只有一个:CI如何知道当前请求来自哪个域名,以及如何根据域名切换到对应的配置。理解了这一点,后面的配置方法就好理解了。
CI获取当前域名的方式很直接,可以通过$_SERVER['HTTP_HOST']拿到浏览器请求的主机名。所有的多域名方案,本质上都是在这个值的基础上做判断和分发。
二、基于config配置的多域名识别方法
这是最常用也最稳妥的方式。打开application/config/config.php,把原来写死的base_url改成动态获取:
$config['base_url'] = ''; $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'www.ipipp.com'; // 根据域名决定协议 $https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'); $config['base_url'] = ($https ? 'https://' : 'http://') . $host . '/';
这样改完之后,无论用户从哪个域名进来,CI生成的链接都会自动使用当前域名,避免了硬编码导致的跳转错乱。这一点非常关键,因为多域名项目中最常见的bug就是页面上的链接写死了主域名,用户从m域名进来点一下又跳回了www域名。
接下来处理不同域名的差异化配置。可以在application/config/目录下为每个域名建一个配置文件,比如config_www.php和config_m.php,然后在主配置文件末尾根据域名加载对应的文件:
// application/config/config.php 末尾追加
$host = $_SERVER['HTTP_HOST'];
if (strpos($host, 'm.') === 0) {
$this->load->config('config_m'); // 加载移动端专属配置
} else {
$this->load->config('config_www'); // 加载PC端专属配置
}
注意在config.php里可以用$this->load是因为加载配置时CI已经初始化了相关组件。如果版本较老不支持这种写法,可以改用get_instance()或者在入口文件index.php里提前处理,效果一样。
三、通过Nginx和Apache做域名级别的分发
Web服务器层面的配置是第一步,多个域名必须正确指向到CI项目目录。以Nginx为例,两个域名指向同一份代码:
server {
listen 80;
server_name www.ipipp.com;
root /var/www/ci_project;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
}
}
server {
listen 80;
server_name m.ipipp.com;
root /var/www/ci_project; # 与PC端同一个目录
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
}
}
如果是Apache,只需要一个VirtualHost,把多个ServerName写在一起即可:
<VirtualHost *:80>
ServerName www.ipipp.com
ServerAlias m.ipipp.com test.ipipp.com
DocumentRoot /var/www/ci_project
<Directory /var/www/ci_project>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
这里有个容易踩的坑:CI默认的.htaccess重写规则不需要按域名区分,因为无论哪个域名进来,最终都会路由到index.php,由CI内部再按域名分发。很多人误以为要在服务器层面为每个域名写不同的重写规则,结果把简单问题复杂化了。只有在多个域名指向不同项目目录时,才需要各自独立配置server块或VirtualHost。
四、在控制器和路由层按域名分发逻辑
配置层解决了环境差异,业务层的分发可以借助CI的钩子(Hooks)或者自定义公共控制器。推荐的做法是定义一个基类控制器,在构造函数里判断域名:
// application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
protected $is_mobile = false;
public function __construct() {
parent::__construct();
$host = $_SERVER['HTTP_HOST'];
$this->is_mobile = (strpos($host, 'm.') === 0);
// 移动端跳转到对应控制器目录
if ($this->is_mobile) {
$this->router->set_directory('mobile');
}
}
}
配合在application/controllers/下建立mobile子目录存放移动端控制器,就能实现PC和移动端完全独立的两套业务逻辑,但模型层和类库保持共享。这种结构比在视图里到处写if判断要干净得多。
如果只是模板不同、逻辑相同,也可以只切换视图目录,在MY_Controller里执行$this->load->set_view_path()`或直接用完整的路径加载视图,例如移动端加载mobile/home/index,PC端加载pc/home/index。
五、常见问题与注意事项
第一,session跨域问题。默认情况下PHP的session cookie只对当前域名有效,用户在www域名登录后访问m域名会变成未登录状态。解决办法是统一使用顶级域名的cookie,设置session.cookie_domain为.ipipp.com,这样所有子域名都能读取同一个session。如果是前后端分离的场景,建议改用token机制,从根源上避开cookie跨域限制。
第二,CSRF和cookie配置。config.php里的cookie_domain也要同步设置成顶级域名,否则表单提交、记住登录等功能在子域名下会失效。同时检查allowed_hosts相关的安全配置,确保新加的域名在白名单里,防止Host头伪造攻击。
第三,缓存和静态资源。多域名共用一份代码时,静态资源的引用建议统一走CDN域名或者写成协议相对路径,避免https页面里加载http资源被浏览器拦截。页面缓存如果按URL做key,要确认缓存组件是否把域名算进了key里,否则PC端和移动端可能互相读到对方的缓存页面。
第四,避免在代码里硬编码域名。所有跳转和链接生成尽量使用site_url()、base_url()这类函数,让框架根据当前请求动态生成地址,这样以后新增域名不需要改任何业务代码。
六、从零开始学习CI框架的路线建议
如果是刚接触CI的新手,不建议直接从多域名配置入手。比较合理的学习顺序是:先花一两天通读官方文档的入门部分,理解MVC的基本概念,跑通一个Hello World;然后重点学习URL路由、控制器、模型的写法,亲手做一个简单的增删改查功能;接着再研究类库加载、helpers、钩子这些进阶特性,这时候回头看多域名配置就会觉得顺理成章。
再往后可以学习数据库操作类的查询构造器、事务处理、表单验证和安全类(XSS过滤、CSRF防护),这些是实际项目中每天都要用的东西。最后再接触缓存、单元测试和部署优化。整体来说CI的学习曲线在PHP框架里是最平缓的之一,集中学习两周左右就能承担中小型项目的开发。
多域名配置属于部署层面的知识,掌握了本文的动态base_url、配置文件分域名加载、服务器ServerAlias这几个要点后,应对绝大多数多域名场景都够用了。遇到更复杂的需求,比如不同域名连不同的数据库,同样是在配置加载环节按域名切换,思路完全一致,举一反三即可。
CI框架多域名配置CodeIgniter修改时间:2026-09-06 19:32:44