【发布时间】:2021-04-15 14:24:58
【问题描述】:
我遇到了 PHP 8 路由问题。我正在创建我的 MVC“框架”以了解有关 OOP 的更多信息。我做了路由、控制器和视图——它有效,我很高兴。但我发现我会测试我的创作。这就是问题开始的地方,即如果路径为空(“”),则返回路由中询问的“主页”视图,但如果我在 URL 中输入“/test”,例如,我有一个返回消息“404 Not Found - 在此服务器上找不到请求的 URL。”即使给定的路由已添加到表中。怎么了?
.htaccess 文件
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php [QSA,L]
带有路由的index.php
<?php
/*
* Require Composer
*/
require dirname(__DIR__) . '/vendor/autoload.php';
/*
* Routing
*/
$routes = new Core\Router();
$routes->new('', ['controller' => 'HomeController', 'method' => 'index']);
$routes->new('/test', ['controller' => 'HomeController', 'method' => 'test']);
$routes->redirectToController($_SERVER['QUERY_STRING']);
Router.php 文件
<?php
namespace Core;
class Router
{
/*
* Routes and parameters array
*/
protected $routes = [];
protected $params = [];
/*
* Add a route to the route board
*/
public function new($route, $params = [])
{
/*
* Converting routes strings to regular expressions
*/
$route = preg_replace('/\//', '\\/', $route);
$route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route);
$route = '/^' . $route . '$/i';
$this->routes[$route] = $params;
}
/*
* Get all routes from table
*/
public function getRoutesTable() {
return $this->routes;
}
/*
* Checking if the specified path exists in the route table
* and completing the parameters table
*/
public function match($url)
{
foreach($this->routes as $route => $params) {
if(preg_match($route, $url, $matches)) {
foreach($matches as $key => $match) {
if(is_string($key)) {
$params[$key] = $match;
}
}
$this->params = $params;
return true;
}
}
return false;
}
/*
* Get all params from table
*/
public function getParamsTable() {
return $this->params;
}
/*
* Redirection to the appropriate controller action
*/
public function redirectToController($requestUrl) {
$requestUrl = explode('?', $requestUrl);
$url = $requestUrl[0];
if ($this->match($url)) {
$controller = $this->params['controller'];
$controller = "App\\Controllers\\$controller";
if(class_exists($controller)) {
$controller_obj = new $controller($this->params);
$method = $this->params['method'];
if(method_exists($controller, $method)) {
$controller_obj->$method();
} else {
echo "Method $method() in controller $controller does not exists!";
}
} else {
echo "Controller $controller not found!";
}
} else {
echo "No routes matched!";
}
}
}
查看.php文件
<?php
namespace Core;
class View {
public static function view($file) {
$filename = "../App/Views/$file.php";
if(file_exists($filename)) {
require_once $filename;
} else {
echo "View $file is not exist!";
}
}
}
HomeController 文件
<?php
namespace App\Controllers;
use Core\Controller;
use Core\View;
class HomeController extends Controller {
public function index() {
return View::view('Home');
}
public function test() {
return View::view('Test');
}
}
文件夹结构
网络浏览器中的路由
我在 PHP 8.0 和 Windows 10 中使用 XAMPP。
【问题讨论】:
-
"如果我输入 "/test" " - 你的问题中的“/test” 中的空格是偶然的吗?否则它与“/test”不匹配是有道理的,因为这两个字符串是不同的。
-
是的,我的问题有误。 “/test”是正确的
-
我根本不明白这是如何工作的?
$_SERVER['QUERY_STRING']不是 URL/路径,它只是 URL 中?之后的内容。例如:https://example.com/test/?this-is-the-part-your-router-gets -
当我使用`'REQUEST_URL'`时,我也遇到了同样的问题。
-
REQUEST_URL不是标准参数 afaik。你的意思可能是REQUEST_URI?
标签: php web model-view-controller routes