You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP MVC基础路由异常:内容正常却始终显示404错误

问题根源与修复方案

兄弟,你的问题完全出在Models/Route.php的逻辑设计上——你现在是每注册一个路由就立刻检查URL并输出提示,而不是等所有路由都注册完成后统一判断,这就导致只要当前循环的路由不匹配,就会提前输出404或错误信息,哪怕后面有匹配的路由也会执行,最终出现视图和错误提示共存的情况。

具体问题点拆解

  • 每次调用Route::set()时,都会先把当前路由加入validRoutes,然后立刻对比$_GET['url']:
    • 如果不匹配,就直接检查是否在已注册的路由里(但此时后面的路由还没注册!),所以会误判为404
    • 就算后面有匹配的路由,前面已经输出的404也不会消失
  • 错误的分支逻辑:elseif和else的顺序不对,而且不该在单个路由注册时就触发全局判断

修正后的Models/Route.php代码

<?php
class Route {
    public static $validRoutes = array();
    // 先收集所有路由,不立即执行判断
    public static function set($route, $function) {
        self::$validRoutes[$route] = $function;
    }

    // 所有路由注册完成后,统一处理请求匹配
    public static function dispatch() {
        $url = $_GET['url'] ?? 'index.php'; // 处理URL为空的边界情况

        if (isset(self::$validRoutes[$url])) {
            self::$validRoutes[$url]->__invoke();
        } else {
            echo "404";
        }
    }
}
?>

配套修改其他文件

  1. Routes.php:需要在所有路由注册完成后调用dispatch()方法
<?php
Route::set('index.php', function() {
    Index::CreateView('Index');
});
Route::set('home', function() {
    Index::CreateView('Index');
});

// 最后统一分发请求
Route::dispatch();
?>
  1. index.php:保持原有自动加载逻辑即可,无需改动

为什么这么改?

  • 先把所有路由以路由=>回调函数的形式存储,而不是只存路由字符串,这样能直接通过URL定位到对应的处理逻辑
  • 新增dispatch()方法,等所有路由都注册完毕再统一检查请求URL,避免提前输出错误信息
  • 处理了URL为空的边界情况(比如直接访问域名时,$_GET['url']可能不存在)

这样修改后,访问index.php或home时只会加载对应的视图,只有当路由完全不匹配时才会输出404,不会再出现视图和错误提示共存的问题了。

内容的提问来源于stack exchange,提问作者CwStrange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:21:24