php URL Router 和 Dispatcher 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11700603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 01:54:03  来源:igfitidea点击:

What is the difference between URL Router and Dispatcher?

phpoopurl-rewritingurl-routing

提问by YakumaruBR

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的区别,因为网上搜索有一些有趣的东西,就是不知道是因为它们相似,还是因为它们的功能颠倒了。谁能告诉我它是什么,每个是什么,以及一个例子?

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.

不知道URL Router和Dispatcher的区别,网上内容的问题,有时候好像Dispatcher就是Router,Router好像是Dispatcher,结果不知道各自有什么权利,什么是每一项,以及如何实施每一项。

Thank you.

谢谢你。

回答by Charles Sprayberry

How frameworks and libraries interpret the responsibilities of the Router and Dispatcher are going to be different. What I detail below is how Iinterpret 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.

框架和库如何解释 Router 和 Dispatcher 的职责将有所不同。下面我详细介绍的是如何解释这两个服务的职责。这并不是说这是唯一的解释方式或其他解释是错误的。

The Concepts

概念

Routing

路由

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.

这有点像在加油站或便利店问路。你要穿过城镇,你需要弄清楚如何去最近的旅馆。您进去询问服务员,他们会为您指出正确的方向,或者至少您希望方向是正确的。路由就是这样。对资源的请求,路由器提供请求到达正确资源所需的方向。

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/1234where 1234is the user ID the Router would parse out the ID portion and provide this as part of the directions to the resource.

在大多数主要框架中,您会将特定的请求 URL 路由到将被调用以完成请求的对象和方法。很多时候你会看到路由器也从 URL 中解析出动态参数。例如,如果您通过用户 ID 在/users/1234哪里访问用户1234,路由器将解析 ID 部分并将其作为资源方向的一部分提供。

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.

调度使用来自路由步骤的信息来实际生成资源。如果路由步骤是询问方向,那么调度就是遵循这些方向的实际过程。Dispatching 确切地知道要创建什么以及生成资源所需的步骤,但前提是从路由器获得指示。

The Implementations

实现

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 needto route to an object; as long as the dispatcher can properly get the correct resource you can route to whatever data you want.

在这个例子中,我们不路由到一个对象和方法,而是路由到一个可调用的函数。这也表明您不需要路由到对象;只要调度员可以正确获取正确的资源,您就可以路由到您想要的任何数据。

First we need something to route against. Let's create a simple Request object that we can match against.

首先,我们需要一些可以路由的东西。让我们创建一个简单的 Request 对象,我们可以与之匹配。

<?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;
    }

}

And now we need some way to invoke a configured $handlerfor a given Request.

现在我们需要一些方法来调用$handler为给定请求配置的。

<?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!\n";
            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\n"; });
$router->post('bar', function() { echo "POST bar\n"; });

$dispatcher = new Dispatcher($router);

$dispatcher->handle(new Request('GET', 'foo'));
$dispatcher->handle(new Request('POST', 'bar'));
$dispatcher->handle(new Request('GET', 'qux'));

You can see an example of this implementation in action by checking out http://3v4l.org/gbsoJ.

您可以通过查看http://3v4l.org/gbsoJ来查看此实现的示例。

The Wrap Up

总结

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 $handlermatched against can be turned into an invokable function.

这个示例实现应该传达路由和调度的概念。实际上,执行这些操作比我的示例要多得多。路由器通常会使用正则表达式来匹配请求,并且在匹配时可能会查看其他请求属性。此外,您会看到一些库使用与路由器交互的解析器,以便您可以传递的不仅仅是可调用函数。基本上,解析器将确保$handler匹配的对象可以变成可调用的函数。

Also, there's plenty of examples and implementations for this that you should look at using instead. For my personal projects I like FastRoutefor its ease of use and performance. But, nearly all major frameworks have their own implementations. You should check those out too.

此外,您应该考虑使用大量示例和实现。对于我的个人项目,我喜欢FastRoute的易用性和性能。但是,几乎所有主要框架都有自己的实现。你也应该检查一下。