上一篇中分析了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 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);
} /**Pimple/Container:**/
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;
}

  在项目中还用到了Trait这个类,其实它就相当于公共函数,可以被加载到每个类中,作为那个类的成员函数或属性。但是也存在着一些覆盖、冲突、优先级的问题,详细可见PHP Manual文档。说这个原因在于这个思路很好,不用去非要继承(当然估计也不能抽象),使用就好了,每个类都能用。

  辣椒吧...

  这里有一个个人认为很炫的魔术方法__invoke()。当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。这个魔术方法很炫啊,以调用函数的方式调用一个对象。棒棒哒….

  这个解决了在middleware栈中调用对象顶端middleware的疑惑:
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;
}
$resp = $start($req, $res);就是相当于调用了$start对象自己的__invoke()对象了。
分析下来,整个route被调用的流程大体如下:
     App->run();
          |
     App->process()
          |
     App->callMiddlewareStack()
          |
     App->__invoke()
          |
     route->run()
          |
     route->finalize()
          \
     route->addMiddleware()
          \
     route->__invoke();
  个人认为比较重要点在于:无论是APP还是每个route都有自己的middlewareStack,自己的栈中栈顶是加入的Middleware栈底是自己($this),这个费了我很多时间。第三是一个PHP的知识点,魔术方法__invoke(),可以直接通过函数的方式调用对象,记住是对象哦即obj(arg01,arg02)这样的方式,这时__invoke()方法就被激活了。APP在__invoke()调用了route,route在__invoke中执行了闭包函数。

学习Slim Framework for PHP v3 (五)--route怎么被调用的?的更多相关文章

  1. 学习Slim Framework for PHP v3 (七)--route middleware怎么被add进来的?

    上两篇中分析了route是怎么被加进来的,以及如何被匹配的.这篇说一下route middleware是如何被加进来的,即add进来的.index.php的代码如下: $app->get('/f ...

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

    先标记觉得以后会用到的内容: // add route to the request's attributes in case a middleware or handler needs access ...

  3. 学习Slim Framework for PHP v3 (四)--get()是怎么加进去的?

    看看官网加粗的一句话: At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate ...

  4. 学习Slim Framework for PHP v3 (三)

    继续上一篇的问题,如何动态的添加不同的Module.添加Module是给Middleware用的,用于调用Module的写日志方法.上篇中的写法是在app->add(mv),这时的middlew ...

  5. 学习Slim Framework for PHP v3 ( 二)

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

  6. Migration from Zend Framework v2 to v3

    Migration from Zend Framework v2 to v3 Zend Framework v2 to v3 has been intended as an incremental u ...

  7. 快乐学习 Ionic Framework+PhoneGap 手册1-1{创建APP项目}

    快乐学习 Ionic Framework+PhoneGap 手册1-1 * 前提必须安装 Node.js,安装PhoneGap,搭建Android开发环境,建议使用真机调试 {1.1}= 创建APP项 ...

  8. Java反射机制demo(五)—获得并调用一个类中的方法

    Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...

  9. torchvision的理解和学习 加载常用数据集,对主流模型的调用.md

    torchvision的理解和学习 加载常用数据集,对主流模型的调用 https://blog.csdn.net/tsq292978891/article/details/79403617 加载常用数 ...

随机推荐

  1. Lazy Loading Images

    Use a blank.gif as the src of images, and include the width and height of the final image. HTML: < ...

  2. imindmap7_windows_7.0

    思维导图工具: imindmap7_windows_7.0 iMindMap7.0 和谐包V1.0 22:27:23

  3. 读loadBalance技术的一些笔记

    以前知道loadbalance的原理,但是仅仅是浅浅的了解过,今天看了一篇 10多年前 一位大神级别人物 写的文章 顿时学习了 http://www.linuxvirtualserver.org/zh ...

  4. Swift学习笔记十五

    自动引用计数(Automatic Reference Counting) 和OC一样,Swift用自动引用计数机制来跟踪和管理你应用程序的内存,大多数情况下,你不需要考虑自己管理内存,Swift会自动 ...

  5. Codeforces Round #244 (Div. 2) B. Prison Transfer 线段树rmq

    B. Prison Transfer Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/pro ...

  6. Swift编程语言学习4.3—— 控制语句

    控制传递语句(Control Transfer Statements) 控制转移语句改变你代码的运行顺序,通过它你能够实现代码的跳转.Swift有四种控制转移语句. continue break fa ...

  7. Ubuntu 14.04 Android 使用Maven二 创建自己的Mavenproject

    依据https://code.google.com/p/maven-android-plugin/wiki/GettingStarted 介绍,有两种方法能够创建Mavenproject. 第一种方法 ...

  8. iOS开发——UI篇Swift篇&UISlider

    UISlider override func viewDidLoad() { super.viewDidLoad() titleLabel.text = titleString // Do any a ...

  9. oc-23-static

    #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * ...

  10. oc-16-set,get方法

    S.h #import <Foundation/Foundation.h> /** 解决方案: 1.不用@public修饰 2.我们对象有访问和设置成员变量的两种操作 1>设置值 p ...