__DIR__ 是 dirname(__FILE__) 的编译期常量语法糖,两者返回值完全一致,但 __DIR__ 无函数调用开销、更高效且可读性更强;PHP 5.3+ 原生支持,老项目用 dirname(__FILE__) 仅为兼容低版本。

直接用 __DIR__ 拼接路径再传给 require,是最安全、最推荐的写法,PHP 5.3+ 原生支持,无需额外函数包装。
为什么不用 dirname(__FILE__) 而用 __DIR__
__DIR__ 是 dirname(__FILE__) 的语法糖,两者返回值完全一致,但 __DIR__ 是编译期解析的常量,不调用函数、不产生开销,且更易读。老项目里看到 dirname(__FILE__) 是为了兼容 PHP
- PHP 5.3+ 已全面支持
__DIR__,无需判断版本 -
__DIR__结尾**不带斜杠**,拼接时必须手动加/,例如__DIR__ . '/config.php' - 误写成
__DIR__ . 'config.php'(漏掉/)会导致路径错成/var/wwwconfig.php,这种错误极难排查
require 中路径是相对当前执行入口文件的,不是当前文件
这是最常踩的坑:很多人以为 require 'lib/helper.php' 是相对于当前文件位置找的,其实它始终以「第一次被访问的 PHP 文件」(如 index.php)所在目录为基准。一旦嵌套包含(比如 index.php → a.php → b.php),纯相对路径就会失效。
- 错误写法:
require 'lib/helper.php';—— 依赖include_path或当前工作目录,不稳定 - 正确写法:
require __DIR__ . '/lib/helper.php';—— 明确指向本文件同级或子目录下的文件 - 跨目录写法:
require __DIR__ . '/../config/database.php';—— 注意../是相对于当前文件所在目录,不是入口文件
和 realpath() 搭配是否必要?
一般不需要。__DIR__ 本身已是绝对路径,realpath() 主要用于处理含 ./、../、符号链接的路径归一化。但在以下情况值得加:
立即学习“PHP免费学习笔记(深入)”;
- 路径中存在多层
../,担心越界(如__DIR__ . '/../../../vendor/autoload.php') - 项目部署在有符号链接的环境(如 Docker volume 挂载),需确保解析到真实物理路径
- 需要校验路径是否存在再 require,可先
if (file_exists($path)) { require $path; }
示例:require realpath(__DIR__ . '/../vendor/autoload.php'); 比裸写更健壮,但多数场景下 __DIR__ 直接拼接已足够。
容易忽略的细节:Windows 下的反斜杠问题
__DIR__ 在 Windows 和 Linux 下都返回正斜杠 /(PHP 内部统一处理),所以 __DIR__ . '/foo/bar.php' 在 Windows 上也能正常工作,无需用 str_replace() 或 DIRECTORY_SEPARATOR 替换。
- 唯一例外是手动拼接 Windows 原生路径字符串(如
'C:\path\to\file.php'),这时才需注意转义 - 用
__DIR__构建的路径,无论系统如何,PHP 自动适配底层 I/O 层 - 但调试时用
echo __DIR__;查看路径,Windows 用户可能看到C:/www/project,别误以为要改成反斜杠
真正麻烦的从来不是写法本身,而是团队里有人坚持用 require 'config.php',有人混用 __FILE__ 和 __DIR__,还有人把 getcwd() 当路径基准——这些不一致才是线上报 failed to open stream 的根源。



















