Apache未加载php_module导致浏览器下载.php文件,本质是PHP模块未启用或配置错误:需确认httpd.conf中LoadModule指令路径与版本匹配、AddType/AddHandler正确关联.php后缀、DocumentRoot路径正确、PHPIniDir指向有效php.ini,且扩展无冲突。

Apache 没加载 php_module 模块
浏览器下载 .php 文件,本质是 Apache 把它当成了普通静态文件,没交给 PHP 解析器处理。最常见原因是 php_module 根本没启用。
检查 httpd.conf(通常在 XAMPP\apache\conf\httpd.conf)里是否有这行且未被注释:
LoadModule php_module modules/libphp.so
Windows 下对应的是:
LoadModule php7_module modules/php7apache2_4.dll
注意模块名和路径要跟你的 XAMPP 版本匹配——PHP 8.2 的模块名可能是 php8apache2_4.dll,路径错或版本不匹配都会导致模块加载失败,Apache 启动时可能不报错,但 .php 就不会执行。
立即学习“PHP免费学习笔记(深入)”;
确认后重启 Apache,再看错误日志(XAMPP\apache\logs\error.log)里有没有类似 Cannot load modules/php7apache2_4.dll 的提示。
AddHandler 或 AddType 配置缺失
即使模块加载成功,Apache 还需要知道“遇到 .php 后缀的文件该用哪个处理器”。XAMPP 默认配置通常已包含,但如果手动改过 httpd.conf 或启用了虚拟主机,这部分容易被覆盖或遗漏。
确保配置中有类似以下内容(位置一般在 LoadModule 块之后、<IfModule php_module> 块内):
AddHandler application/x-httpd-php .php
或者更现代的写法(PHP 7.4+ 推荐):
AddType application/x-httpd-php .php
常见错误包括:
- 只写了
.php,漏了.php7、.phtml等扩展名(虽然少见,但自定义后缀时会出问题) - 写成
AddHandler php-script .php—— 这个 handler 名是旧版 CGI 方式用的,对模块模式无效 - 配置放在了
<Directory>块里但作用域太窄,没覆盖到你的项目路径
PHP 文件放在 DocumentRoot 之外或权限受限
Apache 只会执行位于其文档根目录(DocumentRoot)下、且满足 AllowOverride 和 Require 权限的文件。如果把 test.php 放在 XAMPP\htdocs 外面(比如桌面或 D 盘根目录),即使 URL 能访问,Apache 也不会解析它,而是直接返回原始文件供下载。
检查两点:
-
httpd.conf中DocumentRoot和<Directory "...>路径是否一致,比如都是"X:/xampp/htdocs" - 你的 PHP 文件是否真在那个目录下,路径不要有中文或空格(部分旧版 Apache 对 URI 编码处理不稳定)
- 如果是虚拟主机,确认
DocumentRoot指向正确,并且<Directory>块里有Require all granted
临时验证方法:把一个纯文本 info.php 放进 htdocs,内容就一行 <?php phpinfo(); ?>,用 http://localhost/info.php 访问 —— 如果仍下载,说明不是文件位置问题;如果能显示 PHP 信息页,那问题出在你原项目的路径或配置上。
Windows 下 php.ini 路径或扩展冲突
这个坑比较隐蔽:Apache 加载了 php_module,也配了 AddHandler,但启动时 PHP 初始化失败(比如扩展 DLL 找不到或版本不兼容),Apache 会静默降级为“不处理 PHP”,不报错也不执行。
关键检查点:
-
httpd.conf中是否有PHPIniDir "X:/xampp/php"?路径必须指向含php.ini的目录,且不能带尾部斜杠 - 打开
php.ini,确认extension_dir指向正确的扩展目录,比如"X:/xampp/php/ext",且里面存在php_mysqli.dll等基础扩展(哪怕没启用,至少得存在) - 禁用所有第三方扩展(把
extension=行全注释),只留extension=mysqli和extension=mbstring,再重启 Apache 测试
最容易被忽略的是:XAMPP 控制面板里显示 Apache “Running”,不代表 PHP 模块真的就绪——它只检测进程是否存在,不校验模块内部状态。



















