php.ini 的查找順序是 PHP 開發者、運維最常踩的坑之一 —— **「明明改了配置為什麼不生效?」** 90% 是改錯文件、看錯路徑。本文徹底梳理 **Linux、Windows、多版本共存、CLI vs FPM、模塊化加載** 等場景下的定位邏輯,給出一張「定位決策圖」,以後再也不會找錯文件。
1. SAPI 模塊專用位置 (PHPIniDir / --with-config-file-path / -c 參數) 2. PHPRC 環境變量指定路徑 3. 當前工作目錄 (CLI 執行時的 cwd) 4. 編譯時指定的默認路徑 (--with-config-file-path 編譯參數) 5. Windows: 系統目錄 (C:\Windows, C:\WinNT) 6. *nix: /usr/local/lib/php.ini (或 --prefix/lib/php.ini)
| 場景 | 加載方式 | php.ini 實際路徑確定方法 | 驗證命令 |
|---|---|---|---|
| Linux 源碼編譯 | --with-config-file-path=/etc/php/7.4/cli | 編譯參數指定目錄下的 php.ini (如 /etc/php/7.4/cli/php.ini) | php -i | grep "Loaded Configuration File" |
| Linux 包管理器安裝 (apt/yum/dnf) | 模塊化目錄結構 | CLI: /etc/php/7.4/cli/php.iniFPM: /etc/php/7.4/fpm/php.iniApache 模塊: /etc/php/7.4/apache2/php.ini | php -i | grep iniphp-fpm -i | grep ini |
| Windows 安裝包 (MSI) | 安裝目錄 + 系統目錄 | 1. 安裝目錄 (如 C:\PHP\php.ini)2. 若不存在 → 系統目錄 C:\Windows\php.ini | php -i | findstr "Loaded Configuration File" |
| Windows + Apache (php_apache2_4.dll) | Apache httpd.conf PHPIniDir | httpd.conf 中 PHPIniDir "C:/PHP/" 指定目錄下的 php.ini | Apache error_log 或 phpinfo() |
| Windows + IIS (FastCGI) | IIS 處理程序映射 -d 參數 | FastCGI 應用程序參數 -c "C:\PHP\php.ini" 指定 | IIS 管理器 → FastCGI 設置 或 phpinfo() |
| 多版本共存 (Linux) | 各版本獨立 --prefix | 每版本獨立 /usr/local/php/7.4/lib/php.ini, /usr/local/php/8.1/lib/php.ini啟動腳本/服務文件指定 -c 參數 | /usr/local/php/7.4/bin/php -i | grep ini |
| 多版本共存 (Windows) | 各版本獨立目錄 + PHPIniDir/-c | Apache: 每虛擬主機 PHPIniDir "C:/PHP74/"IIS: 每應用程序池 FastCGI -c "C:\PHP81\php.ini" | phpinfo() 顯示的 Loaded Configuration File |
| Docker 容器 | 映像預置或掛載 | 標準路徑: /usr/local/etc/php/php.ini (官方映像)或通過 -v /host/php.ini:/usr/local/etc/php/php.ini 掛載 | docker exec container php -i | grep ini |
→ 找 Loaded Configuration File 行 — **這是運行時真實加載的文件**,絕對權威php -i | grep "Loaded Configuration File" (Linux) / php -i | findstr "Loaded Configuration File" (Windows)php-fpm -i | grep "Loaded Configuration File" (需 FPM 進程用戶權限,或 sudo -u www php-fpm -i)| 誤區 | 真相 |
|---|---|
| 以為只有一個 php.ini | **每個 SAPI (CLI, FPM, Apache, CGI, Embed) 可以有獨立 php.ini**,且通常**各自獨立** |
| 改了 /etc/php.ini 以為全局生效 | 包管理器安裝時,**CLI/FPM/Apache 各有專屬 ini 目錄**,改錯目錄 = 白改 |
| Windows 下以為只看 C:\Windows\php.ini | **Apache PHPIniDir、IIS FastCGI -c、命令行 -c 參數優先級更高**,系統目錄是最後備選 |
| .htaccess / .user.ini 以為能改所有指令 | 僅能覆蓋 **PHP_INI_PERDIR / PHP_INI_USER** 模式的指令 (如 display_errors, memory_limit),**PHP_INI_SYSTEM 指令 (如 upload_max_filesize, max_execution_time) 必須在主 php.ini 中設置** |
| 重啟 Web 服務器就能重新加載 php.ini | **PHP-FPM 需重啟 php-fpm 服務** (systemctl restart php7.4-fpm),Apache 模塊需重啟 Apache,CLI 每次執行自動重讀 |
現代發行版 (Ubuntu 20.04+, CentOS 8+, Debian 10+) 採用 **主 ini + conf.d 片段** 結構:
/etc/php/7.4/fpm/php.ini # 主配置 (只保留核心通用項) /etc/php/7.4/fpm/conf.d/ ├── 10-opcache.ini # Zend Opcache ├── 20-mysql.ini # MySQLi/PDO_MySQL ├── 20-redis.ini # Redis ├── 99-custom.ini # 業務自定義覆蓋 (最後加載,優先級最高)
優勢:包升級不覆蓋自定義、模塊啟用/禁用只需增刪文件、版本控制更清晰。**強烈建議業務自定義配置寫在 99-custom.ini 中**,而非直接改主 ini。
phpinfo() / php -i / php-fpm -i 看 Loaded Configuration File記住這三步,拋棄「感覺改這個大概率對」的玄學操作,**精準定位、精準生效、精準排查**——這才是專業運維的樣子。