DocumentRoot 路径错误、mod_rewrite 未启用或 AllowOverride 限制、PHP 模块未加载或扩展名未注册、SELinux/AppArmor 安全拦截,是 Apache 返回 404 的四大主因,需依序排查 error_log 线索。

Apache 配置里 DocumentRoot 指向错路径就 404
PHP 文件明明放在 /var/www/html/test.php,但访问 http://localhost/test.php 却返回 404,大概率是 DocumentRoot 没配对。Apache 只会从这个目录开始解析 URL 路径,其他位置的文件默认不可达。
- 检查主配置或虚拟主机配置里的
DocumentRoot值,常见错误是写成/var/www却忘了加/html,或拼错为/var/www/htnl - 确认该路径存在且 Apache 进程(通常是
www-data或apache用户)有读取权限:ls -ld /var/www/html
- 改完配置必须重启服务:
sudo systemctl restart apache2
(Debian/Ubuntu)或sudo systemctl restart httpd
(RHEL/CentOS)
.htaccess 不生效导致 PHP 路由 404
用 Laravel、CodeIgniter 等框架时,常依赖 .htaccess 重写 URL。如果 Apache 没启用 mod_rewrite,或 AllowOverride 被设为 None,重写规则就失效,静态文件能访问,但 /user/profile 这类伪路径直接 404。
- 先确认模块已加载:
a2enmod rewrite
(Debian/Ubuntu),或检查httpd.conf中是否包含LoadModule rewrite_module modules/mod_rewrite.so - 在对应
块中把AllowOverride改成All或至少FileInfo:AllowOverride All
- 别漏掉
Options FollowSymLinks,否则mod_rewrite可能拒绝工作
PHP 文件扩展名没注册进 Apache 就当静态资源处理
访问 test.php 页面只显示源码,或返回 404(尤其在启用 MultiViews 时),说明 Apache 根本没把 .php 当作可执行脚本。这通常发生在手动编译 Apache 或禁用默认 PHP 模块后。
- 检查是否加载了 PHP 模块:
apache2ctl -M | grep php
(Ubuntu)或httpd -M | grep php
(CentOS),应看到类似php7_module (shared) - 确保配置中有
AddType application/x-httpd-php .php和相关处理器声明 - 若用
php-fpm,还要核对ProxyPassMatch是否匹配^/(.*\.php(/.*)?)$,路径正则写错一个字符就会 404
SELinux 或 AppArmor 拦截导致 404(非权限 403)
在 CentOS/RHEL 或 Ubuntu 启用强制访问控制的系统上,即使文件路径、权限、模块全对,也可能静默返回 404——因为安全模块阻止了 Apache 访问目标目录。日志里看不到明显报错,error_log 只写 “File does not exist”,其实是被拦在内核层。
立即学习“PHP免费学习笔记(深入)”;
- 临时验证:运行
sudo setenforce 0
(SELinux)或sudo aa-disable
(AppArmor),再试访问。若 404 消失,就是它 - SELinux 下给 Web 目录打标:
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
,然后sudo restorecon -Rv /var/www/html
- AppArmor 需编辑
/etc/apparmor.d/usr.sbin.apache2,添加对应路径的读取规则
404 表面是“找不到”,背后可能是路径、重写、模块、安全策略四层任一环节断掉。逐层排除时,优先看 error_log 里有没有更具体的线索,比如 “script not found or unable to stat”,那基本就是 DocumentRoot 或 ProxyPassMatch 匹配失败;如果连日志都没记录,就得怀疑 SELinux/AppArmor 的静默拦截了。











