DocumentRoot 路径错误、mod_rewrite 未启用或 AllowOverride 限制、PHP 模块未加载或扩展名未注册、SELinux/AppArmor 安全拦截,是 Apache 返回 404 的四大主因,需依序排查 error_log 线索。
PHP 文件明明放在 /var/www/html/test.php,但访问 http://localhost/test.php 却返回 404,大概率是 
DocumentRoot 没配对。Apache 只会从这个目录开始解析 URL 路径,其他位置的文件默认不可达。
DocumentRoot 值,常见错误是写成 /var/www 却忘了加 /html,或拼错为 /var/www/htnl
www-data 或 apache 用户)有读取权限:ls -ld /var/www/html
sudo systemctl restart apache2(Debian/Ubuntu)或
sudo systemctl restart httpd(RHEL/CentOS)
用 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 可能拒绝工作访问 test.php 页面只显示源码,或返回 404(尤其在启用 MultiViews 时),说明 Apache 根本没把 .php 当作可执行脚本。这通常发生在手动编译 Apache 或禁用默认 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在 CentOS/RHEL 或 Ubuntu 启用强制访问控制的系统上,即使文件路径、权限、模块全对,也可能静默返回 404——因为安全模块阻止了 Apache 访问目标目录。日志里看不到明显报错,error_log 只写 “File does not exist”,其实是被拦在内核层。
sudo setenforce 0(SELinux)或
sudo aa-disable(AppArmor),再试访问。若 404 消失,就是它
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?",然后
sudo restorecon -Rv /var/www/html
/etc/apparmor.d/usr.sbin.apache2,添加对应路径的读取规则404 表面是“找不到”,背后可能是路径、重写、模块、安全策略四层任一环节断掉。逐层排除时,优先看 error_log 里有没有更具体的线索,比如 “script not found or unable to stat”,那基本就是 DocumentRoot 或 ProxyPassMatch 匹配失败;如果连日志都没记录,就得怀疑 SELinux/AppArmor 的静默拦截了。