PHP 項目遷移、多環境部署(開發/測試/生產)、子目錄訪問時,include/require 路徑失效是高頻災難。Perl 時代更慘,PHP 雖支持相對路徑,但「相對於誰?」始終令人困惑:相對於當前執行腳本,而非被包含文件所在目錄。
「以項目根目錄為基準,構建絕對路徑常量;所有包含操作均使用基於此常量的絕對路徑。」
在入口文件(如 index.php、api.php、cli.php)第一行定義:
<?php
// 入口文件:public/index.php
define('APP_ROOT', realpath(__DIR__ . '/..')); // 指向項目根目錄
// 或 PHP 5.3+ 更簡潔
define('APP_ROOT', __DIR__ . '/..'); // 但建議 realpath 解析符號鏈接
require_once APP_ROOT . '/config/bootstrap.php';
config/bootstrap.php:
<?php
// 核心目錄常量
define('CONFIG_DIR', APP_ROOT . '/config');
define('LIB_DIR', APP_ROOT . '/lib');
define('MODEL_DIR', APP_ROOT . '/app/models');
define('VIEW_DIR', APP_ROOT . '/app/views');
define('CACHE_DIR', APP_ROOT . '/var/cache');
define('LOG_DIR', APP_ROOT . '/var/log');
// 自動加載器(Composer 或自定義)
require_once APP_ROOT . '/vendor/autoload.php'; // 推薦 Composer PSR-4
// 錯誤處理、時區、編碼等全局初始化
date_default_timezone_set('Asia/Shanghai');
ini_set('default_charset', 'UTF-8');
<?php
// 任何文件中
require_once CONFIG_DIR . '/database.php';
require_once LIB_DIR . '/functions/helpers.php';
include VIEW_DIR . '/header.php';
// 動態包含(插件、模塊)
$module = 'user';
$file = MODULE_DIR . "/$module/controller.php";
if (is_file($file)) require_once $file;
現代 PHP 專案強烈建議使用 Composer 自動加載,徹底消除路徑煩惱:
// composer.json
{
"autoload": {
"psr-4": {
"App\\": "app/",
"Lib\\": "lib/"
},
"files": ["lib/functions/helpers.php"]
}
}
執行 composer dump-autoload 後,直接 use App\Models\User; 即可,無需任何 require。
| 錯誤做法 | 後果 | 正確做法 |
|---|---|---|
require '../config.php' | 在不同深度目錄調用失效 | require CONFIG_DIR . '/config.php' |
require $_SERVER['DOCUMENT_ROOT'] . '/config.php' | 虛擬主機/子目錄部署時 DOCUMENT_ROOT 不準 | 基於 __DIR__ 推導項目根目錄 |
在被包含文件中再次 require_once 'config.php' | 相對路徑基於執行腳本,極易出錯 | 被包含文件不再包含配置,依賴入口已加載 |
硬編碼 /var/www/html/project/config.php | 遷移服務器需全量替換 | 常量/環境變量配置 |
命令行腳本無 $_SERVER['DOCUMENT_ROOT'],同樣用 __DIR__ 定位:
<?php
// bin/cron_job.php
define('APP_ROOT', realpath(__DIR__ . '/..'));
require_once APP_ROOT . '/config/bootstrap.php';
// 業務邏輯...
「相對路徑在開發機可用,絕對路徑在生產環境可靠。」通過入口文件定義根目錄常量 + 配置文件集中派生子目錄常量 + 業務代碼統一引用常量,配合 Composer 自動加載,可徹底解決 PHP 包含路徑的移植性、可維護性問題。