PHP7.3.6(XAMPP)下$_SERVER["DOCUMENT_ROOT"]为空的问题及解决
问题原因
这个问题的核心原因非常明确:你是通过命令行(CLI模式)运行PHP脚本的,而非通过Apache Web服务器访问。
- 当你通过浏览器访问
phpinfo.php时,PHP是以Apache的Web SAPI模式运行的,会读取Apache配置文件(httpd.conf)中的DocumentRoot值,并将其注入到$_SERVER['DOCUMENT_ROOT']中,所以能看到正确的路径。 - 但如果是直接双击脚本、用命令行执行
php xxx.php,PHP会以CLI模式启动,这种模式下完全独立于Apache,不会加载Apache的任何配置变量,因此$_SERVER['DOCUMENT_ROOT']会是空字符串。你提供的var_dump输出里的argv、argc参数,以及PHP_SELF显示的本地磁盘完整路径,也能佐证这一点。
替代解决方案
根据你的使用场景,有两种方向的解决办法:
场景1:确实需要用CLI模式运行脚本
- 手动定义DOCUMENT_ROOT:在脚本开头直接赋值,简单粗暴且有效:
$_SERVER['DOCUMENT_ROOT'] = 'C:/xampp/htdocs'; - 利用PHP内置常量动态获取:如果脚本的位置相对固定,可以用
__DIR__(当前脚本所在目录)结合realpath来推导根目录,避免硬编码路径:// 假设脚本直接放在htdocs下 $docRoot = realpath(__DIR__); // 如果脚本在htdocs的子目录下,比如htdocs/test/xxx.php,就用: // $docRoot = realpath(__DIR__ . '/../'); $_SERVER['DOCUMENT_ROOT'] = $docRoot; - 通过环境变量传递:运行脚本前先设置环境变量,再执行脚本:
然后在脚本里可以这样获取:set DOCUMENT_ROOT=C:\xampp\htdocs && php xxx.php$_SERVER['DOCUMENT_ROOT'] = getenv('DOCUMENT_ROOT');
场景2:误操作,本应通过Web服务器访问
直接在浏览器中访问你的脚本即可,比如输入http://localhost/xxx.php,此时PHP以Web SAPI模式运行,$_SERVER['DOCUMENT_ROOT']会自动加载httpd.conf中设置的值。
持久化设置方法(让CLI模式自动携带DOCUMENT_ROOT)
如果经常需要用CLI模式运行脚本,不想每次都手动设置,可以通过以下方式持久化配置:
修改PHP的自动前置文件:
- 找到XAMPP中CLI模式使用的
php.ini文件(可以在命令行执行php --ini查看加载的配置文件路径)。 - 在
php.ini中找到auto_prepend_file配置项,修改为:auto_prepend_file = "C:/xampp/htdocs/set_doc_root.php" - 创建
set_doc_root.php文件,放在C:/xampp/htdocs目录下,内容如下:if (empty($_SERVER['DOCUMENT_ROOT'])) { $_SERVER['DOCUMENT_ROOT'] = realpath('C:/xampp/htdocs'); }
这样每次CLI运行PHP脚本时,都会自动加载这个文件,为
$_SERVER['DOCUMENT_ROOT']赋值。- 找到XAMPP中CLI模式使用的
设置系统环境变量:
- 在Windows系统中,打开「系统属性」→「高级」→「环境变量」,添加一个系统变量:
- 变量名:
DOCUMENT_ROOT - 变量值:
C:\xampp\htdocs
- 变量名:
- 重启命令行窗口后,运行PHP脚本时就可以通过
getenv('DOCUMENT_ROOT')获取该值,也可以手动赋值给$_SERVER['DOCUMENT_ROOT']。
- 在Windows系统中,打开「系统属性」→「高级」→「环境变量」,添加一个系统变量:
内容的提问来源于stack exchange,提问作者my80data my80data
相关产品推荐
相关产品推荐

