Apache虚拟主机DocumentRoot必须指向public目录,因CI4的index.php位于public下;需配置AllowOverride All、启用mod_rewrite、设置APP_ENV和APP_DEBUG环境变量,并确保base_url()路径与实际资源位置一致。

Apache 虚拟主机 DocumentRoot 必须指向 public 目录
CodeIgniter 4 默认把入口文件 index.php 放在 public 子目录里,不是项目根目录。如果 Apache 的 DocumentRoot 指向项目根(比如 /var/www/myapp),用户访问时会直接看到目录列表或 403 错误——因为 index.php 不在 Web 可访问路径下。
正确做法是把 DocumentRoot 明确设为 public 目录:
DocumentRoot "/var/www/myapp/public"
<Directory "/var/www/myapp/public">
AllowOverride All
Require all granted
</Directory>
-
AllowOverride All是必须的,否则.htaccess里的重写规则不生效 - 别漏掉
<Directory>块,否则即使路径对了也会返回 403 - 修改后要
sudo systemctl reload apache2(Ubuntu/Debian)或sudo apachectl graceful(macOS)才生效
启用 mod_rewrite 并确认 .htaccess 生效
CodeIgniter 依赖 URL 重写隐藏 index.php。常见现象是:首页能打开,但点击“About”或任何其他路由就 404——本质是 Apache 没转发请求到 index.php。
检查三件事:
- 运行
a2enmod rewrite启用模块(Ubuntu/Debian),或确认LoadModule rewrite_module modules/mod_rewrite.so在httpd.conf中未被注释(macOS / CentOS) -
AllowOverride必须设为All(不能是None或FileInfo),否则.htaccess被忽略 -
public/.htaccess文件必须存在且内容完整(CI4 官方包自带,别手动删或清空)
一个快速验证方式:在 public/.htaccess 末尾加一行 Redirect 302 /test-rewrite 1,访问 /test-rewrite 看是否跳转。不跳?说明重写根本没走。
APP_ENV 和 APP_DEBUG 要在 Apache 环境变量中显式设置
CodeIgniter 4 从环境变量读取 APP_ENV 和 APP_DEBUG,而不是靠 .env 文件自动加载(尤其在 CLI 或 Apache 下)。如果没设,APP_ENV 默认是 production,APP_DEBUG=false,导致错误全被吞掉,只显示白屏或 “Whoops!” 页面。
在虚拟主机配置里加这两行:
SetEnv APP_ENV development SetEnv APP_DEBUG true
- 别写成
SetEnv APP_DEBUG "true"—— 字符串"true"在 PHP 中仍为true,但 CI4 内部用的是严格字符串比较,只认小写true(无引号) - 生产环境务必改回
SetEnv APP_DEBUG false,否则敏感信息可能泄露 - 如果用的是 PHP-FPM,这些变量得通过
php_admin_value[env[APP_ENV]]方式传,不是SetEnv
URL 重写后 CSS/JS 资源 404?检查 base_url() 和静态资源路径
虚拟主机配好、重写也通了,但页面样式错乱、控制台报一堆 GET /css/app.css 404 —— 这不是 Apache 配置问题,而是 CodeIgniter 的资源路径生成逻辑没对齐。
关键点:
-
base_url()默认返回的是当前域名根路径(如https://app.local/),所以base_url('css/app.css')生成的是/css/app.css - 但你的 CSS 实际放在
public/css/app.css,而 Apache 的DocumentRoot已经是public,所以这个路径是对的 - 真正出问题的情况是:你把资源放到了
public/assets/css/,却还用base_url('css/app.css')—— 少写了assets/ - 或者你在
.env里改了app.baseURL,但值末尾没加/(如写成app.baseURL=https://app.local),会导致所有资源路径拼接错误
建议统一用 base_url('assets/css/app.css'),并在 public/ 下建 assets/ 目录放所有前端资源,避免和框架默认路径冲突。
路径层级和环境变量传递这种事,看着琐碎,但少设一个 SetEnv 或多写一个斜杠,调试两小时都未必想到点上。










