結論先行
| 函數/常量 | 返回值 | 受包含關係影響 |
getcwd() | 當前執行腳本的工作目錄 | 否,始終返回主腳本所在目錄 |
__FILE__ | 當前文件的完整路徑 | 是,在被包含文件中返回被包含文件路徑 |
dirname(__FILE__) | 當前文件所在目錄 | 是,同 __FILE__ |
實測驗證
目錄結構
/folder/random/
├── foo.php (主腳本)
└── bar/
└── bar.php (被包含文件)
foo.php
<?php
echo getcwd() . "\n"; // /folder/random
echo dirname(__FILE__) . "\n"; // /folder/random
echo "-------\n";
include 'bar/bar.php';
bar/bar.php
<?php
echo getcwd() . "\n"; // /folder/random ← 不變!
echo dirname(__FILE__) . "\n"; // /folder/random/bar ← 變了!
執行結果
/folder/random
/folder/random
-------
/folder/random
/folder/random/bar
深度解析
getcwd() —— 進程級工作目錄
- 返回 PHP 進程的 Current Working Directory
- 由執行命令的位置決定(如
php /path/foo.php)
- 包含文件不會改變它,無論在哪個 include 文件中調用,結果一致
- 可被
chdir() 修改
__FILE__ / dirname(__FILE__) —— 文件級路徑
- 魔術常量,編譯時解析
- 在被包含文件中,返回被包含文件的路徑/目錄
- 常用於構建相對當前文件的路徑:
require dirname(__FILE__) . '/config.php';
- PHP 5.3+ 推薦使用
__DIR__ 直接替代 dirname(__FILE__)
實戰應用場景
場景 1:框架入口文件獲取項目根目錄
// index.php (位於 public/)
define('ROOT_PATH', dirname(__DIR__)); // 獲取項目根目錄
場景 2:類庫文件加載同目錄配置
// src/Service/Api.php
$config = require __DIR__ . '/../config/api.php'; // 相對當前文件定位
場景 3:CLI 腳本處理相對路徑參數
// 用戶執行:php script.php ../data/file.txt
$input = $argv[1];
$absolute = getcwd() . DIRECTORY_SEPARATOR . $input; // 解析為絕對路徑
現代 PHP 最佳實踐
- 優先使用
__DIR__ (PHP 5.3+) 替代 dirname(__FILE__)
- 項目根目錄建議在入口文件用
define('BASE_PATH', __DIR__) 固定
- 避免在運行時依賴
getcwd(),因其可被任意 chdir() 修改
- Composer 自動加載機制已解決絕大多數路徑問題