学习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个方面的思路,设计中有的两点是:
$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做些什么,暂时没思路。
学习Slim Framework for PHP v3 ( 二)的更多相关文章
- 学习Slim Framework for PHP v3 (四)--get()是怎么加进去的?
看看官网加粗的一句话: At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate ...
- 学习Slim Framework for PHP v3 (五)--route怎么被调用的?
上一篇中分析了get()如何加入新的route的,这篇来分析route是如何被调用的. 首先,route是在routers里保存,router有在container中存放.container提供了ge ...
- 学习Slim Framework for PHP v3 (三)
继续上一篇的问题,如何动态的添加不同的Module.添加Module是给Middleware用的,用于调用Module的写日志方法.上篇中的写法是在app->add(mv),这时的middlew ...
- 学习Slim Framework for PHP v3 (七)--route middleware怎么被add进来的?
上两篇中分析了route是怎么被加进来的,以及如何被匹配的.这篇说一下route middleware是如何被加进来的,即add进来的.index.php的代码如下: $app->get('/f ...
- 学习Slim Framework for PHP v3 (六)--route怎么被匹配的?
先标记觉得以后会用到的内容: // add route to the request's attributes in case a middleware or handler needs access ...
- WCF学习之旅—TcpTrace工具(二十六)
止文(WCF学习之旅—TcpTrace工具(二十五))介绍了关于TcpTrance的一种使用方式,接下来介绍第二种使用方式. 三.通过ListenUri实现基于tcpTracer的消息路由 对于路由的 ...
- Java学习-039-源码 jar 包的二次开发扩展实例(源码修改)
最近在使用已有的一些 jar 包时,发现有些 jar 包中的一些方法无法满足自己的一些需求,例如返回固定的格式,字符串处理等等,因而需要对原有 jar 文件中对应的 class 文件进行二次开发扩展, ...
- Qlik Sense学习笔记之Mashup开发(二)
date: 2019-01-26 11:28:07 updated: 2019-01-26 11:28:07 Qlik Sense学习笔记之Mashup开发(二) 1.Mobile SPA UI Fr ...
- 学习Coding-iOS开源项目日志(二)
继续前篇:<学习Coding-iOS开源项目日志(一)>,接着本第二篇<学习Coding-iOS开源项目日志(二)>讲解Coding-iOS开源项目. 前言:作为初级程序员,想 ...
随机推荐
- arm_cm4.c关于kinetis的修改
/***********************************************************************/ /* * Initialize the NVIC t ...
- Eclipse和Android Studio中的DDMS使用时什么不同?
http://www.jb51.net/softjc/454131.html Eclipse和Android Studio中的DDMS使用时什么不同? 相信很多经常开发Android应用的朋友应该都接 ...
- zTree实现基本树
zTree实现基本树 1.实现源代码 <!DOCTYPE html> <html> <head> <title>zTree实现基本树</title ...
- 将博CMS安全分析报告-橘皮书
一.使用IBM的AppScan和Acunetix应用程序漏洞扫描将博CMS5.5,得出一些漏洞. 此番扫描大小共23种类型问题,其中高危漏洞有三个,中危漏洞9个,低级漏洞11个.注意这 ...
- Swift学习笔记十四
Deinitialization 当类的实例对象即将要被释放时,会立即调用deinitializer,通过deinit关键字来定义deinitializer,和initializer一样,它也只存在于 ...
- Mysql权限控制 - 允许用户远程连接
Mysql为了安全性,在默认情况下用户只允许在本地登录,可是在有此情况下,还是需要使用用户进行远程连接,因此为了使其可以远程需要进行如下操作: 一.允许root用户在任何地方进行远程登录,并具有所有库 ...
- Android程序开发0基础教程(一)
程序猿学英语就上视觉英语网 Android程序开发0基础教程(一) 平台简单介绍 令人激动的Google手机操作系统平台-Android在2007年11月13日正式公布了,这是一个开放源码的操 ...
- MySQL错误:Can't connect to MySQL server (10060)
转自:http://database.51cto.com/art/201107/274565.htm 当远程连接MySQL数据库的时候显示Can't connect to MySQL server ( ...
- /bin/bash: line 0: fg: no job control一般解决方法
測试版本号:CDH5.0,(Hadoop2.3) 在使用windows调用Hadoop yarn平台的时候,一般都会遇到例如以下的错误: 2014-05-28 17:32:19,761 WARN or ...
- oc-15-匿名对象
/** 匿名对象 1.访问成员变量--->只能给成员变量设置值,只能成功1次,每次都是新的对象. 2.调用方法时类似类方法: 跟类方法区别:匿名对象创建对象了,开辟空间了. */ #import ...