ホームページ  >  記事  >  バックエンド開発  >  PHP v3 のスリム フレームワークを学ぶ (2)

PHP v3 のスリム フレームワークを学ぶ (2)

WBOY
WBOYオリジナル
2016-06-23 13:18:101285ブラウズ

昨日、index.php に get(pattern, clouser) を追加することで、ローカル URL を指定された処理クラスにルーティングして、処理後 (ここではデータベースに保存するという意味です)、応答を返すことができると言いました。デバイスに表示される閲覧時。

昨日残った最後の疑問は、 アプリのコンテナに独自のキーを追加できますか? 今日も解決されていません。

今日の作業は、処理完了後にログを記録するミドルウェアを追加することです。

Slim3.0ではSlim2のように各MiddlewareにApplicationを追加しなくなったため、Middleware内でAppデータを取得することが困難になると同時に、コンテナにキーを追加する問題も解決されていません。したがって、私のアイデアは次のとおりです:

1. APP クラスはミドルウェアを追加してルーターを起動するためにのみ使用されます

2. 関連するビジネス処理のためにルーターをモジュールとして登録します

3. モジュールにはロギングを実装するクラスが含まれます。

4. ミドルウェアで対応するクラスを指定します。

実はまだ疑問があるんですが、ミドルウェアの __invoke() メソッドはいつ実行されるのかということです。コードを辿ってみると、ミドルウェアを追加する際に、次のようなコードがあることが分かりました:

protected function addMiddleware(callable $callable)    {        echo 'add middle ware';        if ($this->middlewareLock) {            throw new RuntimeException('Middleware can’t be added once the stack is dequeuing');        }        if (is_null($this->stack)) {            $this->seedMiddlewareStack();        }        $next = $this->stack->top();        $this->stack[] = function (ServerRequestInterface $req, ResponseInterface $res) use ($callable, $next) {            $result = call_user_func($callable, $req, $res, $next);            if ($result instanceof ResponseInterface === false) {                throw new UnexpectedValueException(                    'Middleware must return instance of \Psr\Http\Message\ResponseInterface'                );            }            return $result;        };        return $this;    }

このコードで最も重要なのは、次の 2 つの文です:

$next = $this->stack- >top();

$this->stack[] = function();

この stack[] はミドルウェアスタックに追加されますが、この関数 () が重要なもので、いわゆる
依存性の注入。 興味深いのは、関数全体が実行されるのではなく、実行される場合はミドルウェアの __invoke() メソッドが実行されることです。いつ実行するか? 論理的に言えば、コード内の app->run() で呼び出される現在のミドルウェア シーケンスに到達したときに実行されます。コードでわかるように、中間スタックの最上位要素を呼び出します。

public function callMiddlewareStack(ServerRequestInterface $req, ResponseInterface $res)    {        if (is_null($this->stack)) {            $this->seedMiddlewareStack();        }        /** @var callable $start */        $start = $this->stack->top();        $this->middlewareLock = true;        $resp = $start($req, $res);        $this->middlewareLock = false;        return $resp;    }

$start($req,$res) のときに、匿名関数 function が実行され、カスタム ミドルウェアの __invoke() が実行されました。

これは

Dependency Injectionの概念であるはずですが、今はよく理解できていないので、後でよく勉強する必要があります。

これでソースコードはある程度理解できました。

上記の4つの考え方を踏まえて、設計のポイントは次の2つです:

1. Moduleを本体とし、そのモジュールにLogやDBなどの必要なライブラリを追加します

2.ミドルウェアのモジュール、モジュールを呼び出す方法はログを書き込むことです

モジュールにログとDBを追加するのは簡単ですが、ミドルウェアをモジュールよりも先に登録して、それに関連付けられたものが使えないのが原因です。登録時に module が NULL になっているため、後で実行するとモジュールが見つからず、さまざまなメソッドが存在しないというエラーが発生します。

$app->add(Example\MiddleWare\MyMiddleware::instance());$app->post('/homepage', function ($request, $response, $args) use ($app) {    Example\Module\Replace::instance($request,$response)->excute();    return $response;});

この場合、まずモジュールを存在させてモジュールをインスタンス化し、エラーが報告されないようにモジュールとミドルウェアのコードを次のように変更します。

/**** Module**/public function init($request,$response){    $this->request = $request;    $this->response = $response;    $this->excute();}public abstract  function excute();

そしてindex.phpにミドルウェアとルーターを追加すると以下のようなコードになります:

/*** Middleware*/    self::$middleWare = is_null(self::$middleWare)?new MyMiddleware($module):self::$middleWare;    return self::$middleWare;}public function __construct($module){    $this->module = $module;}

このようにしてMiddlewareでLogWriteを完了する機能が実現されるのですが、問題はModuleとMiddlewareの指定です。他のルータを登録するときにモジュールを動的に変更できない場合。これは良くない!

他にもっと良い方法はありますか? フレームワークには匿名関数(Closer)がたくさんあります。クローザーの解決策はありますか?

ミドルウェアでモジュールを動的に指定する問題を解決する必要があります。または、アプリで何ができるのかわかりません。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。