看看官网加粗的一句话:

  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. JS 去字符串空格

    str为要去除空格的字符串:去除所有空格: str = str.replace(/\s+/g,""); 去除两头空格: str = str.replace(/^\s+|\s+$/g ...

  2. 【M17】考虑使用缓式评估

    1.缓式评估其实就是拖延战术,直到逼不得已的时候才去计算.缓式评估的使用场景有: 2.引用计数,考虑String,String是一个内含char指针(char指针以'\0'结束)的资源管理类,正常情况 ...

  3. SGU 531. Bonnie and Clyde 线段树

    531. Bonnie and Clyde 题目连接: http://acm.sgu.ru/problem.php?contest=0&problem=531 Description Bonn ...

  4. C++ Code_Slider

    主题 1. 滑块控件属性设置 2. 使用滑块控件设置颜色 3. 显示Slider的数值 4. 5.      属性 滑块控件属性设置 //代码设置属性      代码:: ////////////// ...

  5. 使用iOS手势UIGestureRecognizer

    UIKit中包含了UIGestureRecognizer类,用于检测发生在设备中的手势.UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,它有下面一些子类用于处理具体的手势 ...

  6. 大一C语言结课设计之《学生信息管理系统》

    第一次写这么长的程序,代码仅供參考,有问题请留言. /* ** 学生信息管理系统 ** IDE:Dev-Cpp 4.9.9.2 ** 2014-6-15 */ #include <stdio.h ...

  7. Lvalue, Rvalue, Xvalue, Prvalue, Glvalue

    c++11中关于什么是lvalue, 什么是rvalue, 什么是xvalue, 什么是prvalue, 什么是… 一直搞得我晕头转向的, 今天下定决心一定要把它搞定, 写了一个程序来判断lvalue ...

  8. 数据连接命令join

    join主要用来将两个相关联的文件连接起来.两个文件相关联的意思是指这两个文件中有一些字段是关联的,例如两个文件的第1个字段都是学号,且每个学生的学号是唯一的.像这种具有唯一性关联的文件,就可以使用j ...

  9. MAMP Pro3.5注册码

    MAMP这个就不用介绍了,堪称MAC下的苏菲玛索,官方下载地址:https://www.mamp.info/en/mamp-pro/   ,400多大洋,土豪朋友请直接购买吧,正版还是要支持的. 和我 ...

  10. 小白日记49:kali渗透测试之Web渗透-XSS(三)-存储型XSS、DOM型XSS、神器BEFF

    存储型XSS与DOM型XSS [XSS原理] 存储型XSS 1.可长期存储于服务器端 2.每次用户访问都会被执行js脚本,攻击者只需侦听指定端口 #攻击利用方法大体等于反射型xss利用 ##多出现在留 ...