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
相关产品推荐
相关产品推荐

