学习Slim Framework for PHP v3 ( 二)

  昨天说到能够成功将本地的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;
    }

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

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

  在 $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;
});

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

/***
* Module
**/
public function init($request,$response){
    $this->request = $request;
    $this->response = $response;
    $this->excute();
}
public abstract  function excute();
/**
* Middleware
*/
    self::$middleWare = is_null(self::$middleWare)?new MyMiddleware($module):self::$middleWare;
    return self::$middleWare;
}

public function __construct($module){
    $this->module = $module;

}

   然后在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;
});

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

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

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

 

  

时间: 2024-12-18 03:47:26

学习Slim Framework for PHP v3 ( 二)的相关文章

学习Slim Framework for PHP v3 (四)

看看官网加粗的一句话: At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response. That’s it. 那么它是如何分发接收到的Request的呢,这几天就来研究这个事情. 先看看为了让请求进入到index.php 需要对Apache做什么.配置如下,其实也是通常配置而已: # Dir

学习Slim Framework for PHP v3 (一)

因为公司的项目用到是slim 框架,所以想把它学习一下.在公司用到是Slim2版本,现在官网已经到达 Slim3的版本了.官网地址:http://www.cnblogs.com/lmenglliren89php/. 首先按照官网的教程,安装Slim: 1.curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer 2.composer requi

学习Slim Framework for PHP v3 (三)

继续上一篇的问题,如何动态的添加不同的Module.添加Module是给Middleware用的,用于调用Module的写日志方法.上篇中的写法是在app->add(mv),这时的middleware是全局的.其实可以给每个route添加middleware,这个思路是通过阅读官方文档获得的,所以说文档还是要读的. 有了上面的思路之后,就可以给每个route添加middleware了.先上代码: $app->post('/homepage', function ($request, $resp

学习Slim Framework for PHP v3 (四)--route怎么被调用的?

上一篇中分析了get()如何加入新的route的,这篇来分析route是如何被调用的. 首先,route是在routers里保存,router有在container中存放.container提供了get()方法获取里面的元素,性质类似于Set().这个性质见Slim\Container的get()和Pimple\Container的 offsetGet()方法. /**Slim/Container:**/ /** * Finds an entry of the container by its

学习Slim Framework for PHP v3 (六)--route怎么被匹配的?

先标记觉得以后会用到的内容: // add route to the request's attributes in case a middleware or handler needs access to the route $request = $request->withAttribute('route', $route); 或许以后可以在Middleware中拿到route做些其他的事情. 上篇已经分析到route是在APP的__invoke()中被调用的,这里来看看怎么匹配route的

学习编程之Python篇(二)

学习编程与学习踢球.学习演奏并无差别,最佳方式就是不断练习,所以我们鼓励你敲些代码,看看会发生什么,如果这些代码头一次不起作用,没关系,再来,看看你能否把它们纠正过来. 首先是一个简单的快速入门程序,让我们通过了解这个程序的细节,来熟悉Python. 第一项任务:给定半径,计算一个圆的周长和面积. 程序分解: 1.  提示用户输入半径: 2.  应用数学公式,根据获得的半径,得出周长和面积: 3.  输出结果. 代码1.1 运行程序的最简单方法是在IDLE编辑器里打开它,然后选择Run->Run

HTML5学习之智能表单(二)

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> </head> <body> <form

Android 布局学习之——Layout(布局)具体解释二(常见布局和布局參数)

 [Android布局学习系列]   1.Android 布局学习之--Layout(布局)具体解释一   2.Android 布局学习之--Layout(布局)具体解释二(常见布局和布局參数)   3.Android 布局学习之--LinearLayout的layout_weight属性   4.Android 布局学习之--LinearLayout属性baselineAligned的作用及baseline    Layout Parameters(布局參数): 在XML文件里,我们常常看到类

Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

[Android布局学习系列]   1.Android 布局学习之——Layout(布局)详解一   2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)   3.Android 布局学习之——LinearLayout的layout_weight属性   4.Android 布局学习之——LinearLayout属性baselineAligned的作用及baseline    Layout Parameters(布局参数): 在XML文件中,我们经常看到类似与lay