You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CodeIgniter 4中通过单一源码运行多个子域名并解决重定向报错问题

如何在CodeIgniter 4中通过单一源码运行多个子域名并解决重定向报错问题

兄弟,我完全懂你现在的痛点——长期维护的多子域名应用,还要单源码避免重复部署,现在主域名跑的好好的,子域名一访问就重定向报错,下面咱们一步步把问题解决掉:

一、先搞定服务器端配置(这是单源码运行的基础)

首先得让服务器把所有子域名的请求都指向同一个CI4项目的public目录,不管是Nginx还是Apache都得这么配置:

Nginx配置示例

server {
    listen 80;
    server_name *.yourdomain.com; # 通配符匹配所有子域名
    root /path/to/your/ci4-project/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.1-fpm.sock; # 换成你的PHP-FPM路径
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Apache配置示例

在虚拟主机配置或者项目根目录的.htaccess里加这段:

<VirtualHost *:80>
    ServerAlias *.yourdomain.com
    DocumentRoot "/path/to/your/ci4-project/public"
    <Directory "/path/to/your/ci4-project/public">
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

别忘了确保Apache开启了mod_rewrite和mod_vhost_alias这两个模块哦。

二、动态设置baseURL(解决重定向报错的核心)

你说要动态改Config/App.php的baseURL,直接改配置文件太死板,CI4支持动态重载配置,咱们在应用启动时自动适配子域名:

  1. 先打开app/Config/App.php,给$baseURL设个默认值(主域名):
public string $baseURL = 'https://yourdomain.com/';
  1. 去app/Controllers/BaseController.php的构造函数里加逻辑,自动识别子域名并更新baseURL:
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
    parent::initController($request, $response, $logger);

    // 获取当前请求的主机名
    $host = $request->getServer('HTTP_HOST');
    // 只处理咱们自己域名下的子域名
    if (str_ends_with($host, '.yourdomain.com')) {
        // 动态设置对应子域名的baseURL
        config('App')->baseURL = "https://{$host}/";
    }
}

这样每个子域名请求过来,baseURL都会自动变成对应的子域名地址,重定向时就不会跳错地方了。

三、加载子域名专属配置(logo、头部这些)

既然要从数据库取每个子域名的专属内容,咱们直接在BaseController里搞定:

  1. 先建个subdomains数据表,存每个子域名的专属配置:
CREATE TABLE subdomains (
    id INT AUTO_INCREMENT PRIMARY KEY,
    domain VARCHAR(255) NOT NULL UNIQUE,
    logo_url VARCHAR(255),
    header_config TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

把每个子域名的logo地址、头部配置啥的存进去就行。

  1. 回到BaseController,加一段加载配置的逻辑:
protected $subdomainConfig;

public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
    parent::initController($request, $response, $logger);

    // 先设置baseURL
    $host = $request->getServer('HTTP_HOST');
    if (str_ends_with($host, '.yourdomain.com')) {
        config('App')->baseURL = "https://{$host}/";
    }

    // 从数据库拉取当前子域名的专属配置
    $this->subdomainConfig = $this->db->table('subdomains')
        ->where('domain', $host)
        ->get()
        ->getRow();

    // 如果没找到对应配置,直接跳主域名或者显示错误页
    if (!$this->subdomainConfig) {
        return redirect()->to('https://yourdomain.com/');
    }

    // 把配置共享给所有视图,直接就能用
    view()->setData('subdomainConfig', $this->subdomainConfig);
}

这样所有继承BaseController的控制器都能直接用$this->subdomainConfig,视图里也能直接调用$subdomainConfig->logo_url来显示专属logo了。

四、重定向报错的额外坑要注意

除了baseURL的问题,还有几个常见坑会导致重定向报错:

  • 别硬写路由地址:所有跳转都用CI4的redirect()或者route_to(),比如用return redirect()->route('home');,别硬写https://yourdomain.com/home,不然子域名下跳转还是会跑主域名。
  • CSRF配置要适配多子域名:打开Config/Security.php,把$csrfCookieDomain设为.yourdomain.com(前面的点不能丢),这样所有子域名都能共享CSRF cookie:
public string $csrfCookieDomain = '.yourdomain.com';
  • 清缓存!清缓存!清缓存!:CI4会缓存配置,改完配置一定要删掉writable/cache/目录下的缓存文件,不然旧配置还会生效。

五、最后测试验证

  1. 先去DNS服务商那里设置通配符解析,把*.yourdomain.com指向你的服务器IP。
  2. 配置好服务器后,随便访问一个子域名(比如test.yourdomain.com),在视图里加<?= config('App')->baseURL ?>看看是不是对应子域名的地址。
  3. 测试重定向功能,比如在控制器里写个跳转,看是不是跳转到子域名对应的路径,而不是主域名。

这样下来,单源码跑多子域名的需求就实现了,重定向报错的问题也能解决啦。

备注:内容来源于stack exchange,提问作者İsmail Serbest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 10:18:01