getcwd()返回启动命令时的工作目录而非脚本目录,应使用chdir(dirname(__file__))或chdir(__dir__)切换至脚本所在目录以确保相对路径正确解析。

CLI模式下getcwd()返回的不是脚本所在目录
PHP CLI执行时,getcwd()返回的是**启动命令时的当前工作目录**,而非PHP脚本文件所在的目录。比如你在/home/user目录下运行php /var/www/app/cli.php,getcwd()结果仍是/home/user,不是/var/www/app。这就导致所有相对路径(如require '../config/db.php')都以错误起点解析,直接报failed to open stream: No such file or directory。
dirname(__FILE__)才是脚本真实位置的可靠来源
必须用dirname(__FILE__)(或 PHP 5.3+ 的__DIR__)获取脚本自身所在目录。它不依赖执行上下文,永远指向该PHP文件的绝对路径。
- ✅ 正确做法:
chdir(dirname(__FILE__));—— 立即切换到脚本所在目录,后续所有相对require/include就按预期工作 - ❌ 错误假设:
getcwd()+ 手动拼接路径 —— 在crontab、systemd或远程调用中极易断裂 - ⚠️ 注意:
__DIR__末尾不含斜杠,拼接子路径时要加/,例如require __DIR__ . '/lib/helper.php';
为什么修改include_path经常失效
很多人试图用ini_set('include_path', ...)把脚本目录加进搜索路径,但实际效果不稳定:
- 某些PHP版本或SAPI(如某些Docker镜像)会忽略CLI下的
include_path修改 -
require '../a.php'中的..仍以getcwd()为基准解析,不走include_path - 嵌套
require(A require B,B require C)中,C的路径又会相对于B的位置计算,逻辑迅速失控
crontab和systemd中尤其要主动chdir
定时任务默认在用户家目录(如/root或/home/deploy)启动,getcwd()完全不可控。不显式chdir(dirname(__FILE__)),哪怕脚本本身路径写对了,它的被依赖文件也会加载失败。
- crontab建议写法:
* * * * * cd /var/www/app && php cli.php或在脚本开头强制chdir - systemd服务中,
WorkingDirectory可设,但不如脚本内chdir(__DIR__)彻底,因为后者不依赖外部配置 - 调试时加一行
echo "CWD: " . getcwd() . "\nScript dir: " . __DIR__ . "\n";,立刻看清差异
实际最简健壮写法就是开头两行:
chdir(dirname(__FILE__)); require 'config/database.php';别绕远路——路径问题的核心从来不是“怎么拼”,而是“从哪开始拼”。这个起点,只能靠
__DIR__锁定。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











