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

PHP MVC框架路由异常:仅首页路由可正常访问

问题:PHP简易MVC框架路由仅首页可用,$_SERVER['REQUEST_URI']异常

我正在用PHP构建一个简易MVC框架,访问不同URL时只有首页路由能正常工作。调试发现$_SERVER['REQUEST_URI']仅返回/或触发404页面。以下是Router类、控制器代码及路由配置,求帮忙排查问题。


Router类代码

class Router
{
    private array $handlers = [];

    public function get(string $path, $handler): void
    {
        $this->addHandler('GET', $path, $handler);
    }

    public function post(string $path, $handler): void
    {
        $this->addHandler('POST', $path, $handler);
    }

    private function addHandler(string $method, string $path, $handler): void
    {
        $this->handlers[] = [
            'path' => $path,
            'method' => $method,
            'handler' => $handler
        ];
    }

    public function run()
    {
        $requestUri = parse_url($_SERVER['REQUEST_URI']);
        $requestPath = $requestUri['path'];
        $method = $_SERVER['REQUEST_METHOD'];

        $callBack = null;
        foreach ($this->handlers as $handler) {
            if ($handler['path'] === $requestPath && $method === $handler['method']) {
                $callBack = $handler['handler'];
            }
        }

        if (!$callBack) {
            $response = new Response();
            return $response->setStatusCode(404);
        }


        if (is_string($callBack)) {
            $parts = explode('::', $callBack);
            if (is_array($parts)) {
                $className = array_shift($parts);
                $handler = new $className;
                $method = array_shift($parts);

                $callBack = [$handler,$method];
            }
        }


        call_user_func_array($callBack, [
            array_merge($_POST, $_GET)

        ]);
    }
}

路由注册代码

$router = new Router();

$router->get('/', ProductsController::class . '::showProducts');

$router->get('/productlist', ProductsController::class . '::showProducts');

$router->post('/views/addproduct.php', ProductsController::class . '::create');

$router->post('/', ProductsController::class.'::deleteProduct');

$router->run();

ProductsController控制器代码

class ProductController extends Controller
{
    /**
     * index() 返回数据库表中所有产品
     */
    public function index()
    {
        $connection = new DBConnection();
        $product = new ProductsModel($connection);
        $products = $product->allProducts();

        return $this->loadView('productlist', [
            'products' => $products
        ]);
    }

    /**
     * addProduct 向数据库表中添加新产品
     *
     */
    public function create()
    {
                $connection = new DBConnection();
                $product = new ProductsModel($connection);
                
            if( $_POST['save'] ) {
                $sku = $request->input('sku');
                var_dump($sku);
                $name = $request->input('name');
                $price = $request->input('price');
                $productType = $request->input('productType');
                $weight = $request->input('weight');
                $height = $request->input('height');
                $size = $request->input('size');
                $width = $request->input('width');
                $length = $request->input('length');

                $product->addProduct($sku, $name, $price, $weight, $height, $length, $width, $size, $productType);
            }
           

        return $this->loadView('/addproduct');
    }

    /**
     * deleteProduct 从数据库中删除一个或多个产品
     */
    public function deleteProduct()
    {
        $connection = new DBConnection();
        $deleteProduct = new ProductsModel($connection);

        if (isset($_POST['button_delete'])) {
            if (isset($_POST['selectedID'])) {
                var_dump($_POST['selectedID']);
                $deleteProduct->destroyProduct($_POST['selectedID']);
            }
        }
        header('Location: https://www.techspeed.co.zw/');
    }
}

问题排查与解决方案

1. 服务器URL重写规则缺失(核心问题)

$_SERVER['REQUEST_URI']异常最可能的原因是未配置URL重写,导致所有请求无法正确转发到入口文件(如index.php)。

  • Apache环境:在项目根目录创建.htaccess文件,添加以下规则:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
  • Nginx环境:在站点配置中添加:
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

2. 路由匹配逻辑优化

当前路由是严格相等匹配,若URL末尾带斜杠(如/productlist/)会匹配失败。修改run()方法的路径处理逻辑:

// 获取requestPath后添加
$requestPath = rtrim($requestPath, '/');
$requestPath = $requestPath === '' ? '/' : $requestPath;

3. 控制器类名不一致

路由注册的是ProductsController,但控制器类定义为ProductController(少了s),会导致实例化失败。需统一类名:

class ProductsController extends Controller
{
    // 原有代码保持不变
}

4. POST路由路径规范

当前POST路由/views/addproduct.php指向视图文件,不符合MVC规范,建议改为干净路径如/products/create,同时修改表单提交的action属性对应此路径。

5. 修复create方法未定义变量问题

create方法中使用的$request变量未声明,需改为直接使用$_POST:

if( isset($_POST['save']) ) {
    $sku = $_POST['sku'] ?? '';
    $name = $_POST['name'] ?? '';
    $price = $_POST['price'] ?? '';
    // 其他参数同理修改
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:52:25