apache未执行php而直接下载源码,是因为php模块未加载或handler配置错误:需确认libphp.so是否启用、addhandler/sethandler是否匹配后缀、selinux上下文及权限是否正确,并排除php-fpm与mod_php混用冲突。

Apache没执行PHP,直接下载源码
这是典型的 PHP 模块未启用或配置未生效:用户访问 .php 文件时,浏览器弹出下载对话框,而不是运行脚本。本质是 Apache 把 index.php 当成了普通二进制文件(MIME 类型为 application/octet-stream),根本没交给 PHP 解析器。
检查是否加载了 libphp.so(或 php_module)以及是否设置了正确的 AddHandler 或 SetHandler 是关键。
- 用
apachectl -M | grep php确认php_module是否在已加载模块列表中 - 若无输出,说明模块根本没启用——不是配置错,是压根没加载
- 别只改
httpd.conf,现代发行版(如 Ubuntu/Debian)通常把 PHP 配置拆到/etc/apache2/mods-enabled/php8.x.load和php8.x.conf,要确保这两个文件存在且被包含 - CentOS/RHEL 用的是
php.conf在/etc/httpd/conf.d/下,但必须保证LoadModule php_module modules/libphp.so这行没被注释,且路径真实存在
PHP handler 配置不匹配导致解析失效
即使模块加载成功,如果 handler 没绑定对后缀,Apache 仍会跳过 PHP 处理流程。常见错误是只配了 .php,漏掉 .php7、.phtml,或者新版 Apache(2.4.30+)要求用 SetHandler 替代旧的 AddHandler。
- 确认
<filesmatch></filesmatch>块里用了SetHandler application/x-httpd-php(Apache 2.4 推荐)或AddHandler application/x-httpd-php .php(旧写法,部分环境仍可用) - 如果用了 MPM event + PHP-FPM,则不能用
libphp.so,而应配ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/,此时 handler 必须指向 FPM socket,否则照样下载 - 虚拟主机内配置优先级高于全局,检查
<virtualhost></virtualhost>里是否意外覆盖或清空了 PHP handler
SELinux 或文件权限阻止模块加载
尤其在 CentOS/RHEL 上,libphp.so 被 SELinux 标记为 httpd_modules_t 才能被 Apache 加载;权限不对则 httpd -t 测试时可能静默失败,或报 Cannot load modules/libphp.so into server。
立即学习“PHP免费学习笔记(深入)”;
- 运行
ls -Z /usr/lib64/httpd/modules/libphp.so,确认上下文是system_u:object_r:httpd_modules_t:s0;不是就用chcon -t httpd_modules_t /usr/lib64/httpd/modules/libphp.so - 检查
libphp.so所在目录权限:Apache 主进程以root启动,但子进程降权为apache或www-data,所以模块文件至少需o+r(其他用户可读) -
httpd -t返回语法正确 ≠ 模块真能加载,加-e debug(httpd -t -e debug)能看到更详细的模块加载日志
重启后仍下载?检查 .htaccess 和多版本共存冲突
改动配置后 systemctl restart apache2 不生效,很可能是缓存、旧进程残留,或多个 PHP 版本互相干扰。比如系统装了 PHP 7.4 和 8.2,但 Apache 加载的是 7.4 的模块,而 phpinfo() 显示的是 CLI 的 8.2,造成误判。
- 确认重启命令真正杀掉了所有旧进程:
ps aux | grep httpd看是否还有master进程残留;必要时killall httpd && systemctl start apache2 - 在网站根目录放一个
test.php,内容为<?php phpinfo(); ?>,访问它看实际生效的是哪个 PHP 版本和 SAPI 类型(apache2handler表示模块模式,fpm-fcgi表示代理模式) - 如果项目用了
.htaccess,检查里面是否有RemoveHandler .php或SetHandler default-handler这类覆盖性指令
最麻烦的情况是 PHP-FPM 和 mod_php 混用,或者 Apache 配置里同时存在 LoadModule php_module 和 ProxyPassMatch,两者互斥,留一个,删干净另一个。











