上一篇中分析了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. 【转】android出现注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 注: 某些输入文件使用了未经检查或不安全的操作。 注

    使用Android studio打包应用程序出现如下错误: 注: 某些输入文件使用或覆盖了已过时的 API. 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译. 注: 某些 ...

  2. sc7731 Android 5.1 LCD驱动简明笔记之一

    基于展讯sc7731 - Android 5.1 代码分析浏览.将屏蔽细节,把握整体,并且不涉及其他设备和LCD的交互. 以下对sc7731 lcd大体流程进行简要说明. 第一,lcd 的两个阶段 1 ...

  3. Windows Server Backup 2008 R2 备份Hyper-V

    要备份 Hyper-V 虚拟机从父分区在 Windows Server 2008 上使用 Windows 服务器备份,您必须注册 Microsoft Hyper-V VSS 编写器 Windows 服 ...

  4. python flask model 序列化

    class DictSerializable(object):     def as_dict(self,*args):         result = OrderedDict()         ...

  5. Codeforces Round #342 (Div. 2) C. K-special Tables 构造

    C. K-special Tables 题目连接: http://www.codeforces.com/contest/625/problem/C Description People do many ...

  6. Linux文件时间属性

    Linux文件时间属性                                                                                         ...

  7. Android 手机设置CMWAP 接入点

    Android 手机设置CMWAP 接入点 设置--- 无限控件---移动网络设置---接入点名称----再按菜单---选择新apn 第一步,设置CMNET 上网APN 新建 APN 1.名称:cmn ...

  8. HTML5 <script>元素async,defer异步加载

    原文地址:HTML5′s async Script Attribute原文日期: 2010年09月22日翻译日期: 2013年08月22日 (译者注: 异步加载,可以理解为无阻塞并发处理.) (译者再 ...

  9. 编辑器TP

    http://www.itshipin.com/blog/archives/category/php/thinkphp

  10. poj 3249 Test for Job (DAG最长路 记忆化搜索解决)

    Test for Job Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8990   Accepted: 2004 Desc ...