PHP Apache配错出404怎么修_PHP Apache404错误修正法【说明】

10次阅读

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

PHP Apache配错出404怎么修_PHP Apache404错误修正法【说明】

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-dataapache 用户)有读取权限:
    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”,那基本就是 DocumentRootProxyPassMatch 匹配失败;如果连日志都没记录,就得怀疑 SELinux/AppArmor 的静默拦截了。

text=ZqhQzanResources