URL Router 和 Dispatcher 有什么区别?
我想知道URL Router和Dispatcher的区别,因为网上搜索有一些有趣的东西,就是不知道是因为它们相似,还是因为它们的功能颠倒了.谁能告诉我它是什么,每个是什么,以及一个例子?
I want to know the difference between the URL Router and Dispatcher, because searching on the internet has some interesting things, just do not know if it's because they are similar, or because they reverse the function of each. Can anyone tell me what it is and what each one, and an example?
不知道URL Router和Dispatcher的区别,网上内容的问题,有时候好像Dispatcher就是Router,Router又好像Dispatcher,结果不知道各自的权限是什么,每一个是什么,以及如何实现每一个.
I do not know the differentiate from URL Router to Dispatcher, the question of content they have on the Internet, sometimes it seems the Dispatcher is the Router, and the Router seems Dispatcher, and end up not knowing what the right of each, what is each one, and how implement each one.
谢谢.
推荐答案
框架和库如何解释 Router 和 Dispatcher 的职责将有所不同.下面我将详细说明我如何解释这两个服务的职责.并不是说这是唯一的解释方式或其他解释是错误的.
How frameworks and libraries interpret the responsibilities of the Router and Dispatcher are going to be different. What I detail below is how I interpret the responsibilities of these two services. It is not to say that this is the only way to interpret it or that other interpretations are wrong.
这有点像在加油站或便利店问路.你要穿过城镇,你需要弄清楚如何去最近的旅馆.您进去询问服务员,他们会为您指出正确的方向,或者至少您希望方向是正确的.路由就是这样.对资源的请求,路由器提供请求到达正确资源所需的方向.
This is kinda like asking for directions at a gas station or convenience store. You're going through town and you need to figure out how to get to the nearest hotel. You go in and ask the attendant and they point you off in the correct direction, or at least you hope the directions are correct. Routing is exactly this. A request comes in for a resource, the Router provides the directions necessary for the request to reach the correct resource.
在大多数主要框架中,您会将特定的请求 URL 路由到将被调用以完成请求的对象和方法.很多时候你会看到路由器也从 URL 中解析出动态参数.例如,如果您通过 /users/1234
访问用户,其中 1234
是用户 ID,路由器将解析 ID 部分并将其作为指向资源.
In most major frameworks you're going to be routing a specific request URL to an object and method that will be invoked to complete the request. Often times you'll see the Router also parsing out dynamic arguments from the URL. For example, if you accessed users via /users/1234
where 1234
is the user ID the Router would parse out the ID portion and provide this as part of the directions to the resource.
调度使用来自路由步骤的信息来实际生成资源.如果路由步骤是询问方向,那么调度就是遵循这些方向的实际过程.Dispatching 确切地知道要创建什么以及生成资源所需的步骤,但前提是要从路由器获得指示.
Dispatching uses the information from the Routing step to actually generate the resource. If the Routing step is asking for directions then Dispatching is the actual process of following those directions. Dispatching knows exactly what to create and the steps needed to generate the resource, but only after getting the directions from the Router.
这些示例实现故意非常简单和幼稚.如果没有大幅改进,您不会希望在任何类型的生产环境中使用它.
These example implementations are intentionally very simple and naive. You would not want to use this in any kind of production environment without drastic improvements.
在这个例子中,我们不路由到一个对象和方法,而是路由到一个可调用的函数.这也表明您不需要路由到一个对象;只要调度员能够正确获取正确的资源,您就可以路由到您想要的任何数据.
In this example instead of routing to an object and method we're just gonna route to a callable function. This also demonstrates that you don't need to route to an object; as long as the dispatcher can properly get the correct resource you can route to whatever data you want.
首先我们需要一些东西来路由.让我们创建一个可以匹配的简单 Request 对象.
First we need something to route against. Let's create a simple Request object that we can match against.
<?php
class Request {
private $method;
private $path;
function __construct($method, $path) {
$this->method = $method;
$this->path = $path;
}
function getMethod() {
return $this->method;
}
function getPath() {
return $this->path;
}
}
既然我们可以匹配一些东西,让我们来看看一个简单的路由器实现.
Now that we can match against something let's take a look at a simple Router implementation.
<?php
class Router {
private $routes = [
'get' => [],
'post' => []
];
function get($pattern, callable $handler) {
$this->routes['get'][$pattern] = $handler;
return $this;
}
function post($pattern, callable $handler) {
$this->routes['post'][$pattern] = $handler;
return $this;
}
function match(Request $request) {
$method = strtolower($request->getMethod());
if (!isset($this->routes[$method])) {
return false;
}
$path = $request->getPath();
foreach ($this->routes[$method] as $pattern => $handler) {
if ($pattern === $path) {
return $handler;
}
}
return false;
}
}
现在我们需要一些方法来为给定的请求调用配置的 $handler
.
And now we need some way to invoke a configured $handler
for a given Request.
<?php
class Dispatcher {
private $router;
function __construct(Router $router) {
$this->router = $router;
}
function handle(Request $request) {
$handler = $this->router->match($request);
if (!$handler) {
echo "Could not find your resource!
";
return;
}
$handler();
}
}
现在,让我们把它们放在一起,展示如何使用这些简单的实现.
Now, let's bring it all together and show how to use these simple implementations.
<?php
$router = new Router();
$router->get('foo', function() { echo "GET foo
"; });
$router->post('bar', function() { echo "POST bar
"; });
$dispatcher = new Dispatcher($router);
$dispatcher->handle(new Request('GET', 'foo'));
$dispatcher->handle(new Request('POST', 'bar'));
$dispatcher->handle(new Request('GET', 'qux'));
您可以通过查看 http://3v4l.org/gbsoJ 来查看此实现的示例.
You can see an example of this implementation in action by checking out http://3v4l.org/gbsoJ.
这个示例实现应该传达路由和调度的概念.实际上,执行这些操作比我的示例要多得多.路由器通常会使用正则表达式来匹配请求,并且在匹配时可能会查看其他请求属性.此外,您将看到一些库使用与路由器交互的解析器,以便您可以传递的不仅仅是可调用函数.基本上,解析器将确保匹配的 $handler
可以变成一个可调用的函数.
This example implementation is supposed to communicate the concept of routing and dispatching. Really there's a lot more to performing these actions than my example. Often the Router will use regex to match against a Request and may look at other Request attributes when matching. Additionally you'll see some libraries utilizing a resolver that interacts with the Router so that you can pass more than just callable functions. Basically, the Resolver would ensure that the $handler
matched against can be turned into an invokable function.
此外,您应该考虑使用大量示例和实现.对于我的个人项目,我喜欢 FastRoute 的易用性和性能.但是,几乎所有主要框架都有自己的实现.你也应该检查一下.
Also, there's plenty of examples and implementations for this that you should look at using instead. For my personal projects I like FastRoute for its ease of use and performance. But, nearly all major frameworks have their own implementations. You should check those out too.
相关文章