看看官网加粗的一句话:

  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. [转帖]ExtJs与服务器的交互(一)

    Ext是一个非常好的Ajax框架,其华丽的外观表现确实令我们折服,然而一个应用始终离开不服务器端,因此在实现开发中我们需要对Ext与服务器端的交互技术有较为详细的了解,在开发中才能游刃有余地应用.本文 ...

  2. Codeforces Round #306 (Div. 2) B. Preparing Olympiad dfs

    B. Preparing Olympiad Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/550 ...

  3. 多个非同源的shared_ptr管理对象引起double free

    有多个不同源的shared_ptr管理对象时会出现多次释放对象,这里不同源是指多组间不是通过拷贝构造.复制等手段而来的,即几组shared_ptr是独立声明的. #include<iostrea ...

  4. 【JavsScript】Spine的作者曾经是Backbone的作者

    基于MVC的JavaScript Web富应用开发 Alex MacCaw,是一名Ruby/JavaScript程序员,在开源社区中很有名望,是Spine框架的作者,开发过Taskforce,Soci ...

  5. android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu

    示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现. 实现方法:我们自定义一个ViewGroup实现左右滑动, ...

  6. ChinaASP.Upload 错误 '80040002' You must add our copyright info

    ChinaASP.Upload 错误 '80040002' You must add our copyright info: http://www.chinaasp.com 修改 第一步:在“开始-运 ...

  7. QString,QByteArray和QBitArray之间的转换

    1:QBitArray2QString :也可以转化为整型, 测试程序: 测试输出结果是否和移位结果相同: [cpp] view plaincopyprint?   QBitArray x; int  ...

  8. sqoop1.99.4安装与简介

    1.什么是sqoop clouder公司开发的一个在关系数据库和hdfs,hive之间数据导入导出的一个工具 2.版本及其区别 现在分为sqoop1和sqoop2 1)架构图(sqoop1和hadoo ...

  9. 使用NuGet加载包,发现加载的dll都是最新版,原来少加了参数[-Version]

    使用NuGet获取AutoMapper 发现无法正确加载包,项目版本是3.5,获取的dll版本较高,查资料发现可以通过 “-Version” 指定加载包版本 http://www.mamicode.c ...

  10. soupUI生成webservice客户端代码

    在Apache网站下载axis2软件包,同时本机安装soapUI工具.例如,当前我使用的axis2版本为axis2-1.4-bin.zip,soapUI版本为3.6. Apache Axis下载地址: ...