將 CodeIgniter 專案從 Apache 遷移至 Nginx 時,常遇到首頁正常但內頁全數 404 的情況。本文深入剖析根本原因,提供生產環境就緒的 Nginx 配置範本。
/index.php/controller/method 視為 index.php?/controller/method,自動支援 PATH_INFO。/index.php/controller/method 視為請求 index.php 目錄下的 controller/method 檔案,導致 404。CodeIgniter 預設啟用 $config['uri_protocol'] = 'REQUEST_URI',需 Nginx 正確傳遞完整 URI 給 PHP。
以下為推薦的 server 區塊配置(適用 CI 3.x / 4.x):
server {
listen 80;
server_name example.com;
root /data/wwwroot/example/public; # CI4 指向 public/,CI3 指向專案根目錄
index index.php index.html index.htm;
# 靜態資源快取
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?|map|json)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
access_log off;
}
# 核心:所有非實體檔案請求轉發至 index.php
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
# PHP 處理
location ~ \.php$ {
# 安全性:防止惡意上傳檔案被當作 PHP 執行
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000; # 或 unix:/run/php/php8.1-fpm.sock
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info; # 關鍵:傳遞 PATH_INFO
include fastcgi_params;
# 可選:限制 open_basedir
fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/:/proc/";
}
# 隱藏敏感檔案
location ~ /\.(htaccess|git|env|yml|lock)$ {
deny all;
}
}
index.php 並保留查詢字串。這是單一進入點框架的標準模式。location ~ \.php$ 內部先驗證檔案存在,防止 cgi.fix_pathinfo=1 導致的任意程式碼執行風險。// application/config/config.php (CI3) $config['index_page'] = ''; $config['uri_protocol'] = 'REQUEST_URI'; // app/Config/App.php (CI4) public $indexPage = ''; public $uriProtocol = 'REQUEST_URI';
| 現象 | 可能原因 | 驗證方式 |
|---|---|---|
| 首頁正常、內頁 404 | 缺少 try_files 或 rewrite 規則錯誤 | 檢查 error.log、access.log 請求路徑 |
| 所有頁面 404 / 500 | root 指向錯誤、index.php 權限問題 | ls -la 專案目錄、確認 php-fpm 執行身份 |
| 輸出「No input file specified」 | SCRIPT_FILENAME 路徑錯誤、cgi.fix_pathinfo | 在 index.php 加入 var_dump($_SERVER['SCRIPT_FILENAME']) |
| 靜態檔案 404 | root 未指向 public/ (CI4) 或 rewrite 攔截 | 直接訪問 /css/app.css 觀察 |
location /ci/ {
alias /data/wwwroot/ci/public/; # 必須用 alias,並以 / 結尾
try_files $uri $uri/ /ci/index.php$is_args$args;
location ~ \.php$ {
# 注意:alias 下 SCRIPT_FILENAME 需特殊處理
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
}
}
更多部署運維技巧請參考:《Laravel/Nginx 生產環境最佳實踐》、《PHP-FPM 效能調優指南》、《Docker 部署 PHP 應用完整指南》。正確的 Nginx 配置是框架應用高效穩定運行的基礎。