学习Slim Framework for PHP v3 ( 二)

WBOY
Release: 2016-06-23 13:18:10
Original
1291 people have browsed it

  昨天说到能够成功将本地的URL通过在index.php 中添加get(pattern,clouser)路由到指定的处理类中,处理后(这里指存入数据库中),然后返回response在浏览器中显示。

  昨天最后留的问题是:能不能在App的container中添加自己的key呢,今天还没有解决。

  今天做的工作是:添加一个middleware,在处理完成后记录日志。

  Slim3.0不再像Slim2那样在每个Middleware都添加Application,所以在Middleware中获取App的数据有困难,同时向container中加入key的难题也没有解决呢。所以我的思路是这样:

  1.APP class 只用来添加middleware、启动router;

  2.将router注册为相关业务处理的Moduel;

  3.Moduel中含有实现日志记录的类;

  4.在Middleware中指定所对应的类。

  

  其实我还有一个疑问即middleware的__invoke()方法是何时执行的。追踪代码,发现在添加middleware时有这样一段代码如下:

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;    }
Copy after login

   这段代码中重要的是这两句:

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

      $this->stack[] = function();
   这个stack[]即添加到middleware stack中,但是这个function ()是个重要的东西,也就是所谓的依赖注入。有趣在什么地方的呢,就是现在整个函数是不执行的,如果要执行的就是执行了middleware的__invoke()方法。而什么时候执行呢,逻辑上说就是到当前middleware顺序的时候进行执行,在代码上既 app->run()中调用。它调用的是middle stack 的top元素,有代码为证:

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;    }
Copy after login

  在 $start($req,$res)的时候,那个匿名函数function就会执行,自定义middleware的__invoke()就被执行了。

  这里应该是依赖注入的概念,现在还不是很明白,后面需要好好学习下。

  这算对源码的一些理解。

  根据上面4个方面的思路,设计中有的两点是:

    1.以Module为主体,将Log、DB等需要的lib加入到module中;

   2.在Midllerware中设定Module,调用Module的方法如写日志.

   在Module 中加入Log,DB是好用的,但是在Middleware中加入Module不可以用,原因在于Middleware先于module注册,注册时关联的module是NULL的,在后面执行的时候就找不到module,各种方法不存在的错误。

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

  既然这样的话,那就先让Module存在即实例化module;然后在注册middleware的时候指定module,这样不会报错,对Module 和Middleware 修改代码如下:

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

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

   然后在index.php中,添加middleware和router,代码如下:

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

  这样,在Middleware中完成LogWrite的功能就算实现了,但是问题来了,这里过早的指定了Module和Middleware,如果在注册其他router时不能动态的更改Module。这样不算好!

  有没有其他更好的方法呢,框架里很多匿名函数(Clouser)。是不是能有Clouser的办法解决呢?

  Module在Middleware中动态指定的问题需要解决。或者能用App做些什么,暂时没思路。

 

  

 

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template