web-dev-qa-db-ja.com

URLルーターとディスパッチャーの違いは何ですか?

URLルーターとディスパッチャーの違いを知りたいのですが、インターネットでの検索には興味深いことがいくつかあります。それらが類似しているためか、それぞれの機能が逆になっているためかはわかりません。それが何であり、それぞれが何であるか、そして例を誰かに教えてもらえますか?

私はURLルーターからディスパッチャーへの区別、彼らがインターネットに持っているコンテンツの問題を知りません、時々ディスパッチャーはルーターであるように見え、ルーターはディスパッチャーのようであり、それぞれの権利、何が何であるかを知りませんそれぞれ、そしてそれぞれの実装方法。

ありがとうございました。

27
YakumaruBR

フレームワークとライブラリがルーターとディスパッチャーの責任をどのように解釈するかは異なります。以下で詳しく説明するのは、[〜#〜] i [〜#〜]がこれら2つのサービスの責任をどのように解釈するかです。これがそれを解釈する唯一の方法であるとか、他の解釈が間違っていると言っているのではありません。

コンセプト

ルーティング

ガソリンスタンドやコンビニエンスストアで道案内をするようなものです。あなたは町を通り抜けて、あなたは最も近いホテルに着く方法を理解する必要があります。あなたが入ってアテンダントに尋ねると、彼らはあなたを正しい方向に向かわせます、または少なくともあなたは方向が正しいことを望みます。ルーティングはまさにこれです。リクエストがリソースを受信すると、ルーターはリクエストが正しいリソースに到達するために必要な指示を提供します。

ほとんどの主要なフレームワークでは、特定のリクエストURLを、リクエストを完了するために呼び出されるオブジェクトとメソッドにルーティングします。ルーターがURLから動的引数を解析することもよくあります。たとえば、/users/1234を介してユーザーにアクセスした場合、1234はユーザーIDであり、ルーターはID部分を解析し、これをリソースへの指示の一部として提供します。

派遣

ディスパッチは、ルーティングステップからの情報を使用して、実際にリソースを生成します。ルーティングステップが指示を求めている場合、ディスパッチはそれらの指示に従う実際のプロセスです。ディスパッチは、何を作成するか、リソースを生成するために必要な手順を正確に認識しますが、ルーターからの指示を受け取った後でのみです。

実装

これらの実装例は、意図的に非常に単純で素朴です。大幅な改善なしに、これをあらゆる実稼働環境で使用したくないでしょう。

この例では、オブジェクトとメソッドにルーティングする代わりに、呼び出し可能な関数にルーティングします。これは、オブジェクトにルーティングする必要がないneedことも示しています。ディスパッチャーが適切なリソースを適切に取得できる限り、必要なデータにルーティングできます。

最初に、ルーティングする何かが必要です。照合できる単純な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;
    }

}

何かと照合できるようになったので、簡単なルーターの実装を見てみましょう。

<?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を呼び出す方法が必要です。

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

}

それでは、すべてをまとめて、これらの単純な実装の使用方法を見てみましょう。

<?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'));

http://3v4l.org/gbsoJ をチェックアウトすると、この実装の実際の例を見ることができます。

まとめ

この実装例は、ルーティングとディスパッチの概念を伝えることを想定しています。実際、これらのアクションを実行するには、私の例よりも多くのことが必要です。多くの場合、ルーターは正規表現を使用してリクエストと照合し、照合するときに他のリクエスト属性を調べる場合があります。さらに、呼び出し可能な関数以外のものも渡すことができるように、ルーターと対話するリゾルバーを利用するいくつかのライブラリが表示されます。基本的に、リゾルバーは、照合される$handlerが呼び出し可能な関数に変換されることを保証します。

また、代わりに使用することを検討する必要がある、このための多くの例と実装があります。私の個人的なプロジェクトでは、使いやすさとパフォーマンスの点で FastRoute が好きです。しかし、ほとんどすべての主要なフレームワークには独自の実装があります。あなたもそれらをチェックする必要があります。

78