标签:
看看官网加粗的一句话:
$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 (四)
标签:
原文地址:http://www.cnblogs.com/lmenglliren89php/p/5161772.html