继续上一篇的问题,如何动态的添加不同的Module。添加Module是给Middleware用的,用于调用Module的写日志方法。上篇中的写法是在app->add(mv),这时的middleware是全局的。其实可以给每个route添加middleware,这个思路是通过阅读官方文档获得的,所以说文档还是要读的。
有了上面的思路之后,就可以给每个route添加middleware了。先上代码:
$app->post(‘/homepage‘, function ($request, $response, $args){ Example\Module\Replace::instance()->init($request,$response); return $response; })->add(Example\MiddleWare\MyMiddleware::instance(Example\Module\Replace::instance()));
通过这样的代码就可以给各种post,get等通过add方法添加middleware。这样就基本解决了每个route绑定不同的Module,但是每个Module必须是单例模式的。
一个技术上的问题在于:
Example\Module\Replace::instance()->init($request,$response);与
add(Example\MiddleWare\MyMiddleware::instance(Example\Module\Replace::instance()));中的Replace::instance()到底是哪个先执行的。因为Replace是单例,所以哪个先执行还是一个结果的。但是还是跟踪了一下。可以确定:add(Example\MiddleWare\MyMiddleware::instance(Example\Module\Replace::instance()))是先执行的,这个是PHP编译解释时先做的,因为route里是Closure只注册不执行的。根据官网给出的文档解释APP,route的执行顺序,摘抄一下:
hen you run the Slim application, the Request and Response objects traverse the middleware structure from the outside in. They first enter the outer-most middleware, then the next outer-most middleware, (and so on), until they ultimately arrive at the Slim application itself. After the Slim application dispatches the appropriate route, the resultant Response object exits the Slim application and traverses the middleware structure from the inside out. Ultimately, a final Response object exits the outer-most middleware, is serialized into a raw HTTP response, and is returned to the HTTP client.
图片地址:http://www.slimframework.com/docs/concepts/middleware.html 擦。。。不能粘贴图片吗?!!
其实这个说法是对于有APP Middleware时的执行顺序,如果是route Middleware 那么中间是route。还有所谓的从最外的Middleware开始向内进入APP,也不完全这样,毕竟是需要从App->run方法开始执行请求。总体的过程如下:
app->run()
|
\ /
app->__invoke()
|
\/
route->addMiddleware()
|
\/
myMiddleware->__invoke()
|
\/
myModel->instance()::->init()(在route Middleware 调用时才实例化MyModel)
|
\/
myMiddleware->__invoke() (这里指middleware next后的剩余部分)
以之前的角度看这个图是没有问题的,但是以现在的角度看这个图还是略粗和有点小问题。
这样的话每个route绑定module的问题就解决了,只是Moduel现在是单例了,不知道这样合理与否。或者有必要更深一步了解单例模式的使用场景。
下一篇开始写关于它的内核的理解,即到底是怎样将请求分给每个route的。