index.php代码如下:

$app->get('/forbase', function ($request, $response, $args){
Example\Module\Base::instance()->init($request,$response);
return $response;
})->add(Example\MiddleWare\MyMiddleware::instance(Example\Module\Base::instance()));

APP->get()代码如下:

/**
* Add GET route
*
* @param string $pattern The route URI pattern
* @param mixed $callable The route callback routine
*
* @return \Slim\Interfaces\RouteInterface
*/
public function get($pattern, $callable)
{
return $this->map(['GET'], $pattern, $callable);
}

APP->map()代码如下:

/**
* Add route with multiple methods
*
* @param string[] $methods Numeric array of HTTP method names
* @param string $pattern The route URI pattern
* @param mixed $callable The route callback routine
*
* @return RouteInterface
*/
public function map(array $methods, $pattern, $callable)
{
if ($callable instanceof Closure) {
$callable = $callable->bindTo($this->container);
} $route = $this->container->get('router')->map($methods, $pattern, $callable);
if (is_callable([$route, 'setContainer'])) {
$route->setContainer($this->container);
} if (is_callable([$route, 'setOutputBuffering'])) {
$route->setOutputBuffering($this->container->get('settings')['outputBuffering']);
}
return $route;
}

执行完这个map方法后,这个route就被创建了。

$callable = $callable->bindTo($this->container);
  
用来将$this->container绑定到$callable中,这样$callable就可以访问container里的数据,but我没找到怎么用。这是遗留问题之一。

$route = $this->container->get('router')->map($methods, $pattern, $callable);
  做了两件事:
    1.获取router;
    2.router调用map().

看看Slim\Container类:

class Container extends PimpleContainer implements ContainerInterface
{
/**
* Finds an entry of the container by its identifier and returns it.
*
* @param string $id Identifier of the entry to look for.
*
* @throws ContainerValueNotFoundException No entry was found for this identifier.
* @throws ContainerException Error while retrieving the entry.
*
* @return mixed Entry.
*/
public function get($id)
{
if (!$this->offsetExists($id)) {
throw new ContainerValueNotFoundException(sprintf('Identifier "%s" is not defined.', $id));
}
return $this->offsetGet($id);
}
}
get()会调用$this->offsetGet(),这个方法在Pimple\Container里。
看看PimpleContainer类:
class Container implements \ArrayAccess
{
public function offsetGet($id)
{
if (!isset($this->keys[$id])) {
throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
} if (
isset($this->raw[$id])
|| !is_object($this->values[$id])
|| isset($this->protected[$this->values[$id]])
|| !method_exists($this->values[$id], '__invoke')
) {
return $this->values[$id];
} if (isset($this->factories[$this->values[$id]])) {
return $this->values[$id]($this);
} $raw = $this->values[$id];
$val = $this->values[$id] = $raw($this);
$this->raw[$id] = $raw; $this->frozen[$id] = true; return $val;
}
}

  这个类实现了\ArrayAccess接口,官方的解释是说呢,使得访问对象像访问对象那样,即obj['name']拿到name属性。其实能够像访问数组那样访问对象的原因在于ArrayAccess这个接口里的所有方法,在obj['name']就是访问了obj的offsetGet()方法。可以自己覆写这个方法,实现数据存入哪里已经从哪里取出。

  这两句话也比较有意思:$raw = $this->values[$id];$val = $this->values[$id] = $raw($this);  一开始没搞懂$raw($this)是干什么的,因为经过上一步的$this->values[$id]其实就已经拿到Closure了,应该很应当的想到是Closure的参数。没有搞明白的原因在于我认为这一步就已经执行Closure了。我错了,$raw($this)这里才执行了闭包函数。是不是可以总结为只有Closure被调用了才执行,而调用应该来自 “=“的右侧。

  map()用来创建新的route并添加到router中。

public function map($methods, $pattern, $handler)
{
if (!is_string($pattern)) {
throw new InvalidArgumentException('Route pattern must be a string');
} // Prepend parent group pattern(s)
if ($this->routeGroups) {
$pattern = $this->processGroups() . $pattern;
} // According to RFC methods are defined in uppercase (See RFC 7231)
$methods = array_map("strtoupper", $methods); // Add route
$route = new Route($methods, $pattern, $handler, $this->routeGroups, $this->routeCounter);
$this->routes[$route->getIdentifier()] = $route;
$this->routeCounter++; return $route;
} 

$methods = array_map("strtoupper", $methods); 调用了库函数array_map,用途就是将$methods作为参数出传入'strtoupper'中。

new Route($methods, $pattern, $handler, $this->routeGroups, $this->routeCounter); 创建了新的route。

/**
* Route
*/
class Route extends Routable implements RouteInterface
{
public function __construct($methods, $pattern, $callable, $groups = [], $identifier = 0)
{
$this->methods = $methods;
$this->pattern = $pattern;
$this->callable = $callable;
$this->groups = $groups;
$this->identifier = 'route' . $identifier;
}
}

  router中还给route标识了identify,其实就是'routeXX'的样式。

$route->setContainer($this->container);

$route->setOutputBuffering($this->container->get('settings')['outputBuffering']);为新添加的route设置container和outputBuffering。
最后,app->get()会返回一个route。

route add Middleware代码即index.php 中->add();
route->add()方法其实是使用Routable这个抽象类的。

/**
* A routable, middleware-aware object
*
* @package Slim
* @since 3.0.0
*/
abstract class Routable
{
/**
* Prepend middleware to the middleware collection
*
* @param mixed $callable The callback routine
*
* @return static
*/
public function add($callable)
{
$callable = $this->resolveCallable($callable);
if ($callable instanceof Closure) {
$callable = $callable->bindTo($this->container);
} $this->middleware[] = $callable;
return $this;
}
}

  在add里还是做了一个绑定,让闭包函数可以访问$this->container。接着将Closure装入到middleware[]数组中,在这个closure也就是route middleware run的时候就会将middleware数组中的元素加入到Middleware stack中。通过CallMiddlewareStack来依次执行Middleware。

  至此,APP成功添加了一个route,并且给这个route添加了一个middleware。

代码研磨 Slim v3 (一)--app->get()&route->add()的更多相关文章

  1. 代码研磨 Slim v3 (二)--app->run()

    APP->run()代码如下:   /** * Run application * * This method traverses the application middleware stac ...

  2. 开源电影项目源码案例重磅分析,一套代码发布小程序、APP平台多个平台

    uni-app-Video GitHub地址:https://github.com/Tzlibai/uni-app-video 一个优秀的uni-app案例,旨在帮助大家更快的上手uni-app,共同 ...

  3. 【转】【翻】Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

    转自:http://mrfufufu.github.io/android/2015/07/01/Codelab_Android_Design_Support_Library.html [翻]Andro ...

  4. Android Design Support Library 的 代码实验——几行代码,让你的 APP 变得花俏

    原文:Codelab for Android Design Support Library used in I/O Rewind Bangkok session--Make your app fanc ...

  5. 【代码】Android: 怎样设置app不被系统k掉

    有一种方法可以设置app永远不会被kill,AndroidManifest.xml 中添加: android:persistent="true" 适用于放在/system/app下 ...

  6. 添加静态路由 route add -host 子网掩码 -- 在线解析

    1.215        -----       R(172.16.0.1)      <--------- gw(61.146.164.109) |                       ...

  7. 开启路由转发 - route add -net 0.0.0.0 netmask 0.0.0.0 gateway 192.168.0.131 window tracert 追踪路由

    1.登录方式内网访问172.28.101.0/19网段的方法:在192.168.1.0/24网段的上网机器上,或在自己的操作机上加个192.168.1.0网段的ip,注意不要跟别人设置的冲突了,并添加 ...

  8. 使用route add添加路由,使两个网卡同时访问内外网

    route add命令格式:route [-f] [-p] [Command] [Destination] [mask Netmask] [Gateway] [metric Metric] [if I ...

  9. route add提示: "SIOCADDRT: No such process

    解决方法如下: 原因: There are multiple known causes for this error: - You attempted to set a route specific ...

随机推荐

  1. svn的搭建

    http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407610.html

  2. Adobe Photoshop CC 14.0简体中文特别版32位和64位下载

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  3. FLEX4中的Panel如何实现带自定义图标和按钮

      做过flex开发的程序员都知道,使用flex3中的panel自定义按钮很容易,而且flex3的panel有icon属性.但是flex4的中大部分的控件与flex3中的控件实现方式有很大的变化,同是 ...

  4. [每日一题] OCP1z0-047 :2013-08-06 外表部――相关描述

    这道题目的知识点是要你熟悉外部表,怎么建外部表,外部表的数据是怎么存储的等等.请给出正确答案,并解释A B C D每项,最好用实验测试证明! 外部表的metadata(元数据)是存在数据库中,但它的数 ...

  5. Chrome 开发者工具使用技巧

    最近我花了较多的时间使用 Chrome 的开发者工具.我发现了很多之前没用过的好功能 (或还不是特别需要用到的功能,例如 blackboxing 和 asynchronous stacktraces) ...

  6. android中判断sim卡状态和读取联系人资料的方法

    在写程序中,有时候可能需要获取sim卡中的一些联系人资料.在获取sim卡联系人前,我们一般会先判断sim卡状态,找到sim卡后再获取它的资料,如下代码我们可以读取sim卡中的联系人的一些信息. Pho ...

  7. 利用shell脚本统计文件中出现次数最多的IP

    比如有如下文件test.txt 1  134.102.173.43 2  134.102.173.43 3  134.102.171.42 4  134.102.170.9 要统计出现次数最多的IP可 ...

  8. C# Socket基础(一)之启动异步服务监听

    本文主要是以代码为主..NET技术交流群 199281001 .欢迎加入. //通知一个或多个正在等待的线程已发生事件. ManualResetEvent manager = new ManualRe ...

  9. 微软免费TFS如何设置在客户端独占签出

    最近发现微软给我们提供了免费的TFS,地址:http://tfs.visualstudio.com/, 就注册了一个,但是我发现没办法独占签出. 在公司里,TFS有服务端,所以很好设置,但是注册微软的 ...

  10. VS2012无法安装cocos2d-x-2.1.4 解决方法及VS2012新建coco2d-x项目(一)

    转自:http://www.cnblogs.com/wangpei/admin/EditPosts.aspx?opt=1 (注:此方法是可行,仅供参考,建议大家直接看我的 一见命令解决vs安装并创建c ...