php实现httprouter
PHP 实现 HTTP Router
在 PHP 中实现 HTTP Router 可以通过多种方式完成,以下是一些常见的方法:
使用原生 PHP 实现
通过解析 $_SERVER['REQUEST_URI'] 和 $_SERVER['REQUEST_METHOD'] 来实现路由功能:
$requestUri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$requestMethod = $_SERVER['REQUEST_METHOD'];
$routes = [
'GET' => [
'/' => 'homeController',
'/about' => 'aboutController',
],
'POST' => [
'/contact' => 'contactController',
],
];
if (isset($routes[$requestMethod][$requestUri])) {
call_user_func($routes[$requestMethod][$requestUri]);
} else {
header("HTTP/1.0 404 Not Found");
echo '404 Not Found';
}
使用 FastRoute 库
FastRoute 是一个流行的 PHP 路由库,性能高效且易于使用:
require 'vendor/autoload.php';
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/', 'homeController');
$r->addRoute('GET', '/about', 'aboutController');
$r->addRoute('POST', '/contact', 'contactController');
});
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::NOT_FOUND:
header("HTTP/1.0 404 Not Found");
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
header("HTTP/1.0 405 Method Not Allowed");
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
call_user_func($handler, $vars);
break;
}
使用 Laravel 的路由组件
Laravel 的路由组件可以独立使用,提供更丰富的功能:
require 'vendor/autoload.php';
use Illuminate\Container\Container;
use Illuminate\Events\Dispatcher;
use Illuminate\Http\Request;
use Illuminate\Routing\Router;
$container = new Container;
$request = Request::capture();
$container->instance('Illuminate\Http\Request', $request);
$events = new Dispatcher($container);
$router = new Router($events, $container);
$router->get('/', function () {
return 'Home Page';
});
$router->get('/about', function () {
return 'About Page';
});
$router->post('/contact', function () {
return 'Contact Form';
});
$response = $router->dispatch($request);
$response->send();
使用 Symfony 的 Routing 组件
Symfony 也提供了强大的路由功能:
require 'vendor/autoload.php';
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$routes = new RouteCollection();
$routes->add('home', new Route('/', [
'_controller' => 'homeController',
]));
$routes->add('about', new Route('/about', [
'_controller' => 'aboutController',
]));
$routes->add('contact', new Route('/contact', [
'_controller' => 'contactController',
'_method' => 'POST',
]));
$context = new RequestContext();
$context->fromRequest(Request::createFromGlobals());
$matcher = new UrlMatcher($routes, $context);
try {
$parameters = $matcher->match($context->getPathInfo());
call_user_func($parameters['_controller']);
} catch (Exception $e) {
header("HTTP/1.0 404 Not Found");
}
自定义正则路由
对于更复杂的路由需求,可以使用正则表达式:
$requestUri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$requestMethod = $_SERVER['REQUEST_METHOD'];
$routePatterns = [
'GET' => [
'#^/$#' => 'homeController',
'#^/about$#' => 'aboutController',
'#^/user/(\d+)$#' => 'userController',
],
];
foreach ($routePatterns[$requestMethod] as $pattern => $controller) {
if (preg_match($pattern, $requestUri, $matches)) {
call_user_func($controller, array_slice($matches, 1));
exit;
}
}
header("HTTP/1.0 404 Not Found");
以上方法可以根据项目需求选择适合的实现方式。







