浏览器直接下载PHP文件,说明Apache未解析而是当作二进制文件处理,根本原因是PHP模块未加载或AddHandler/SetHandler未正确配置导致处理器缺失。

Apache 访问 PHP 文件被拒绝,大概率不是权限拒绝(403 Forbidden),而是 Apache 根本没把 .php 当作可执行脚本处理——它要么直接下载文件,要么显示源码,或者返回 404 / 500。核心问题在于「PHP 模块未生效」或「处理器未注册」,而不是系统级访问控制。
为什么浏览器直接下载 .php 文件?
这是最典型的“未解析”现象,说明 Apache 完全没调用 PHP 解释器。根本原因是缺失处理器映射。
-
AddHandler application/x-httpd-php .php没写,或写错 MIME 类型(比如写成application/php) -
AddType application/x-httpd-php .php缺失,导致 Apache 不知道该给.php赋什么 MIME 类型,后续AddHandler就无从绑定 - 配置被放在
.htaccess里,但虚拟主机中AllowOverride是None,整段被忽略 - 用了
php-fpm却还保留AddHandler,两者冲突;正确做法是删掉AddHandler,改用ProxyPassMatch
为什么访问 PHP 文件返回 403 Forbidden?
这真可能是权限问题,但更常是路径或配置误判。Apache 拒绝访问,通常不是 PHP 本身的问题,而是它连文件都读不到。
-
DocumentRoot指向的目录不存在,或 Apache 用户(如www-data或apache)对该目录没有rx权限(注意:目录需有x才能进入) - 目录下没有
index.php,而DirectoryIndex里又没写index.php,Apache 尝试列目录失败 → 默认禁止目录浏览 →403 - SELinux 启用时,
/var/www/html/下的文件上下文不是httpd_sys_content_t,可用ls -Z查,用chcon -R -t httpd_sys_content_t /path修复 -
<directory></directory>块里写了Require all denied,且没覆盖成Require all granted
为什么 httpd -M | grep php 没输出?
模块根本没加载,所有后续配置都白搭。别急着改 .conf,先确认基础链路通不通。
立即学习“PHP免费学习笔记(深入)”;
-
LoadModule php_module modules/libphp.so这行被注释了(开头有#),或路径写错(比如实际在/usr/lib64/httpd/modules/libphp.so,但配置写的是modules/libphp.so) - so 文件确实不存在:
ls /usr/lib64/httpd/modules/libphp*.so看不到任何匹配项 → PHP 模块压根没装,或装的是 FPM 版(不带 Apache DSO) - 架构不匹配:Apache 是 x86_64,但加载了 i386 的
libphp.so→ 启动时报undefined symbol,systemctl status apache2能看到 - Ubuntu/Debian 系统下,模块启用靠
a2enmod php8.1(版本号要对),不是手动改httpd.conf;改完还得systemctl restart apache2
为什么 phpinfo() 显示空白或 500?
模块和处理器都对了,但 PHP 自身初始化失败。这时得看错误日志,不是猜。
- 空白页 + 无报错 →
display_errors = Off且error_log没配,临时加ini_set('display_errors', '1'); error_reporting(E_ALL);到info.php开头 -
500 Internal Server Error→ 立刻查 Apache 错误日志:tail -n 20 /var/log/apache2/error.log(Ubuntu)或/var/log/httpd/error_log(CentOS) - 常见日志线索:
PHP Parse error(语法错)、Unable to load dynamic library(扩展路径错)、Segmentation fault(PHP 和 Apache 版本 ABI 不兼容) -
php.ini路径不对:用php --ini看 CLI 加载的 ini,但 Apache 加载的是另一个(常为/etc/php/8.1/apache2/php.ini),两个配置可能不一致
最容易被忽略的点:同一台机器上多个 PHP 版本共存时,a2enmod 启用的模块名(如 php8.1)和 LoadModule 行里的模块名(如 php_module)必须严格对应;Ubuntu 的 php8.1.load 里写的其实是 LoadModule php8_module,不是 php_module —— 名字对不上,模块就永远加载失败。



















