URL Router和Dispatcher有什么区别?

Yak*_*uBR 27 php oop url-rewriting url-routing

我想知道URL路由器和Dispatcher之间的区别,因为在互联网上搜索有一些有趣的东西,只是不知道是不是因为它们相似,或者因为它们反转了每个的功能.任何人都可以告诉我它是什么,每个人是什么,一个例子?

我不知道从URL路由器到Dispatcher的区别,他们在互联网上的内容问题,有时似乎Dispatcher是路由器,而路由器似乎是Dispatcher,最终不知道每个人的权利是什么,什么是每一个,以及如何实现每一个.

谢谢.

Cha*_*rry 80

框架和库如何解释路由器和调度程序的职责将会有所不同.我下面的细节是怎样解释这两种服务的职责.这并不是说这是解释它的唯一方法或其他解释是错误的.

概念

路由

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

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

调度

Dispatching使用Routing步骤中的信息来实际生成资源.如果"路由"步骤要求指示,则"调度"是遵循这些指示的实际过程.调度确切地知道要创建什么以及生成资源所需的步骤,但只有在从路由器获取指示之后才知道.

实施

这些示例实现有意地非常简单和幼稚.如果没有大幅改进,您不希望在任何类型的生产环境中使用它.

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

首先,我们需要一些东西来对抗.让我们创建一个我们可以匹配的简单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;
    }

}
Run Code Online (Sandbox Code Playgroud)

既然我们可以匹配某些内容,那么我们来看看一个简单的路由器实现.

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

}
Run Code Online (Sandbox Code Playgroud)

现在我们需要一些方法来调用$handler给定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!\n";
            return;
        }

        $handler();
    }

}
Run Code Online (Sandbox Code Playgroud)

现在,让我们将它们整合在一起,并展示如何使用这些简单的实现.

<?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'));
Run Code Online (Sandbox Code Playgroud)

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

总结

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

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