看看官网加粗的一句话:

  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做什么。配置如下,其实也是通常配置而已:

# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
    #DirectoryIndex index.html
    # XAMPP
    DirectoryIndex index.html index.html.var index.php index.php3 index.php4
</IfModule>
  保证了访问目录是直接到index.xxx中来。
  还有在项目下有个.htaccesss,这个文件的作用是判断请求的URL满足条件否,即是否满足RewriteCond的匹配。最后如果条件满足则执行RewriteRule 的内容,这里让它跳转到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()));

  这篇先解决:get是怎么加进去的。在随后的文章里依次解决:route是怎么被调用的;route Middleware是如何加进去的。

  在App.php里有变量container。这个变量的类型是Slim\Container,而Slim\Container 继承 PimpleContainer ,据官网说这个Pimple是一个DI Container,这个还不了解。

public function __construct($container = [])
{
if (is_array($container)) {
$container = new Container($container);
}
if (!$container instanceof ContainerInterface) {
throw new InvalidArgumentException('Expected a ContainerInterface');
}
$this->container = $container;
}
class Container extends PimpleContainer implements ContainerInterface
{
/**
* Create new container
*
* @param array $values The parameters or objects.
*/
public function __construct(array $values = [])
{
parent::__construct($values); $userSettings = isset($values['settings']) ? $values['settings'] : [];
$this->registerDefaultServices($userSettings);
}

 在Container构造方法中会注册相关的DefaultServices包括router,以后所有的route都存在于router中:

  

if (!isset($this['router'])) {
/**
* This service MUST return a SHARED instance
* of \Slim\Interfaces\RouterInterface.
*
* @return RouterInterface
*/
$this['router'] = function () {
return new Router;
};
}

  这个$this['router']其实是调用了Pimple\Container中的 offsetSet()方法,因为Pimple\Container实现了ArrayAccess,因此$this['router']是可用的。

public function offsetSet($id, $value)
{
if (isset($this->frozen[$id])) {
throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));
} $this->values[$id] = $value;
$this->keys[$id] = true;
}

  这样的所有默认设置都存放在values这个变量里,以后拿设置从values里拿就好了。

  在app->get()时,APP类所做的工作:

      一get()/post()函数接受route创建请求。二调用app->map();三调用router->map();四设置route的container和output buffer。

上代码:

/**
* 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);
}
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;
}

同时router类所做的工作:

   当有get、post之类的需要加入时,会在router中的map()方法中生成新的route并且给每个route进行了编号,将这个route加入到router的routes数组中。

上代码:

/**
* Add route
*
* @param string[] $methods Array of HTTP methods
* @param string $pattern The route pattern
* @param callable $handler The route callable
*
* @return RouteInterface
*
* @throws InvalidArgumentException if the route pattern isn't a string
*/
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;
}

  这样的一个过程之后,某个添加的route就放入到router的routes数组中了。再以后APP接收到请求后,会在routes选择合适的route来处理处理请求。

  

  

学习Slim Framework for PHP v3 (四)--get()是怎么加进去的?的更多相关文章

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

    上一篇中分析了get()如何加入新的route的,这篇来分析route是如何被调用的. 首先,route是在routers里保存,router有在container中存放.container提供了ge ...

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

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

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

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

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

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

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

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

  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. 简单的自动化使用--使用selenium实现学习通网站的刷慕课程序。注释空格加代码大概200行不到

    简单的自动化使用--使用selenium实现学习通网站的刷慕课程序.注释空格加代码大概200行不到 相见恨晚啊 github地址 环境Python3.6 + pycharm + chrom浏览器 + ...

  9. linux下/etc/profile /etc/bashrc /root/.bashrc /root/.bash_profile这四个配置文件的加载顺序

    目录 一.关于linux配置文件 二.验证四个配置文件的加载顺序 三.结论 一.关于linux配置文件 1.linux下主要有四个配置文件:/etc/profile ./etc/bashrc ./ro ...

随机推荐

  1. C#制作艺术字

    相信 Word  中的 艺术字 功能大家都不陌生, 前面这个 "Word" 单词就是它所为. 今天, 我们就利用C#来制作几款自己的艺术字, 可能会对我们了解字体图像的制作原理有一 ...

  2. Orchard官方文档

    开始使用 安装Orchard 通过Orchard zip文件安装 使用WebMatrix开发Orchard Dashboard总览 创建你的第一个Orchard站点 导航和菜单 添加博客 新增管理媒体 ...

  3. bootstrap适配移动端

    上次在pythonanywhere上挂上去的页面,是这个样子的 而在手机上看是这个样子的 总之简直不能看= = 看了一下学校几个微信公众号的页面.都是用的bootstrap,好吧我也去试试看好了. 在 ...

  4. Linux内核探讨-- 第七章

    本文是个人分析<Linux内核设计与实现>而写的总结,欢迎转载,请注明出处: http://blog.csdn.net/dlutbrucezhang/article/details/136 ...

  5. 安卓高手之路之 WindowManager

    安卓中的画面不是纯粹由window组成.而是改成了window+view的组织模式.window是一个顶层窗口的概念.view就相当于在window内的控件.而subwindow则是依附于window ...

  6. 安装luinxWEB

    Webmin的安装很简单,下面就详细说一下安装步骤. 1.用ssh客户端软件登陆服务器2.切换目录到root下,命令是:cd /root/3.下载Webmin的安装文件,命令是:wget http:/ ...

  7. TP复习7

    //编写search方法,实现搜索 public function search(){ //获取post的数据,根据数据组装查询的条件,根据条件从数据库中获取数据,返回给页面中遍历 if(isset( ...

  8. JVM系列文章(四):类载入机制

    作为一个程序猿,只知道怎么用是远远不够的. 起码,你须要知道为什么能够这么用.即我们所谓底层的东西. 那究竟什么是底层呢?我认为这不能一概而论.以我如今的知识水平而言:对于Web开发人员,TCP/IP ...

  9. php内核探索

    http://www.nowamagic.net/librarys/veda/special/PHP%E5%86%85%E6%A0%B8%E6%8E%A2%E7%B4%A2 关注PHP 源代码 Zen ...

  10. [022]c++虚函数、多态性与虚表

    原文出处:http://my.oschina.net/hnuweiwei/blog/280894 目录[-] 多态 虚函数 纯虚函数 虚表 一般继承(无虚函数覆盖) 一般继承(有虚函数覆盖) 多重继承 ...