用__dir__拼接绝对路径最稳,因require解析相对路径以当前脚本目录为基准,多层嵌套易失效;__dir__返回当前文件绝对路径,配合dirname()或字符串拼接可精准定位文件,避免跨环境路径错误。

用绝对路径拼接 __DIR__ 是最稳的方式,相对路径在多层嵌套下极易失效。
为什么相对路径 require 会突然找不到文件
PHP 的 require 解析相对路径时,基准是「当前执行脚本所在目录」,不是项目根目录,也不是浏览器访问路径。比如 views/user/profile.php 里写 require '../config.php',它会去 views/../config.php → config.php;但同一行代码如果放在 admin/logs/list.php 里,就会去找 admin/../config.php → admin/config.php,显然错。
- 所有以
.或..开头的路径(如./lib/db.php、../init.php)都会跳过include_path,只按当前脚本位置硬算 - 没有所谓“网站根目录”概念——
/config.php是系统根目录,不是你项目的根 - 开发环境和线上服务器的目录结构稍有不同,这类错误往往只在线上爆发
用 __DIR__ 拼出绝对路径才是正解
__DIR__ 返回当前文件所在目录的绝对路径(不含尾部斜杠),配合 dirname() 或字符串拼接,能精准定位任意层级的文件。
- 引入同级目录的
config.php:require __DIR__ . '/config.php'; - 引入上级目录的
bootstrap.php:require dirname(__DIR__) . '/bootstrap.php'; - 引入项目根目录下
lib/Helper.php:require __DIR__ . '/../lib/Helper.php';(假设当前文件在src/下) - 若项目结构固定,可提前定义常量:
define('ROOT_DIR', dirname(__DIR__)); require ROOT_DIR . '/config/database.php';
别碰 include_path 和 URL 引入
include_path 看似能统一路径,但它只对「不带 ./.. 的裸文件名」生效(如 require 'db.php'),而这种写法完全掩盖了文件位置,后期维护极难定位;更危险的是,有人会尝试 require 'http://localhost/lib/init.php',这依赖 allow_url_include=On,线上环境基本禁用,且存在远程代码执行风险。
-
include_path在 CLI 模式和 Web 模式下默认值可能不同,跨环境易出问题 - 任何含
http://或https://的require都应视为错误写法 - 即使本地能跑通,也绝不等于它安全或可移植
批量引入目录下所有 PHP 文件的实用写法
需要加载整个 helpers/ 目录?别手写一堆 require,用 glob() + require_once 更可靠:
foreach (glob(__DIR__ . '/helpers/*.php') as $file) {
require_once $file;
}
注意点:
-
glob()不递归子目录,要递归得用RecursiveIteratorIterator或scandir()手动遍历 - 确保
helpers/目录存在且 PHP 有读权限,否则glob()返回空数组,后续什么都不会发生——不会报错,但逻辑缺失 - 始终用
require_once,避免类重复定义致命错误
路径问题从来不是“试试看哪个点号多就行”,而是每个 require 调用都必须明确知道它最终解析成哪个物理路径。调试时直接 echo __DIR__; 或 var_dump(realpath($path)); 看一眼,比猜半天快得多。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











