解æãã®ï¼
ããããæ ¸å¿â¦â¦â¦ããªãï¼ï½
åååºã¦ãããæ¬å½ããã
vendor/slim/slim/Slim/App.php
ã®__invoke()ã¡ã½ããã
// Get the route info $routeInfo = $request->getAttribute('routeInfo');
ãªãã¨ãªãæ³åã¯ã§ãããã ãã©ãèºèºãªãvar_dumpãã¦ç¢ºèªï½
NULL
â¦â¦â¦ããï¼
ã¡ã¨å
ã«ãæãã«getAttribute()ã確èªãã¦ã¿ã¾ããã
vendor/slim/slim/Slim/Http/Request.php
public function getAttributes() { return $this->attributes->all(); }
protected $attributes;
public function __construct( -ä¸ç¥- $this->attributes = new Collection();
ãµãâ¦â¦â¦
public function withAttribute($name, $value) { $clone = clone $this; $clone->attributes->set($name, $value); return $clone; }
ã¨ãã¯ãããã ãã©ã大æ¬ã«å¯¾ãã¦ããããããsetAttributeãçãªã®ã¯ãªãã£ã½ããªãã
ãªãã ãï¼
ã¾ããããã
ããããã¦
vendor/slim/slim/Slim/App.php
// If router hasn't been dispatched or the URI changed then dispatch if (null === $routeInfo || ($routeInfo['request'] !== [$request->getMethod(), (string) $request->getUri()])) { $request = $this->dispatchRouterAndPrepareRoute($request, $router); $routeInfo = $request->getAttribute('routeInfo'); }
ãµãâ¦â¦ããã®iféã£ãå¾ã®$routeInfoã¯ã©ããªããã ãï¼
array(4) {
[0]=>
int(1)
[1]=>
string(6) "route0"
[2]=>
array(1) {
["name"]=>
string(4) "gallu"
}
["request"]=>
array(2) {
[0]=>
string(3) "GET"
[1]=>
string(35) "http://dev.example.com:8080/hello/gallu"
}
}
ãããã£ã¡ã§äºæ³éãã®ãå
¥ã£ã¦ããã
â¦â¦â¦ãªãã¨ãªããURIã«ãã©ã¡ã¿ããããããï¼ï¼
ã¡ã¨å®é¨ãã¦ã¿ããã
public/index.php
$app = new \Slim\App; $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name\n"); return $response; }); $app->get('/hoge', function (Request $request, Response $response, array $args) { $response->getBody()->write("Hello, hoge\n"); return $response; });
hogeãã追å ã
â¦â¦ãã£ã±ãNULLããéãã®ãã
ã¡ã¨ãããã®æ·±è¿½ãã¯ä¸æ¦ãæ¢ãã¦ãããã
ãã¨ã¯ç´åã®dispatchRouterAndPrepareRoute()ã軽ãæ°ã«ãªãã®ã§ã軽ãç®ã«é²è¦§ã
ã¡ã¨ä¸æãªã¨ãããå¤ãã®ã§ãä¸æ¦ãã¾ãä½å½ããã
protected function dispatchRouterAndPrepareRoute(ServerRequestInterface $request, RouterInterface $router) { $routeInfo = $router->dispatch($request); var_dump($routeInfo); if ($routeInfo[0] === Dispatcher::FOUND) { echo "into if\n"; $routeArguments = []; foreach ($routeInfo[2] as $k => $v) { $routeArguments[$k] = urldecode($v); } var_dump($routeArguments); $route = $router->lookupRoute($routeInfo[1]); $route->prepare($request, $routeArguments); // add route to the request's attributes in case a middleware or handler needs access to the route $request = $request->withAttribute('route', $route); } $routeInfo['request'] = [$request->getMethod(), (string) $request->getUri()]; var_dump($routeInfo); exit; return $request->withAttribute('routeInfo', $routeInfo); }
array(3) {
[0]=>
int(1)
[1]=>
string(6) "route0"
[2]=>
array(1) {
["name"]=>
string(4) "gallu"
}
}
into if
array(1) {
["name"]=>
string(4) "gallu"
}
array(4) {
[0]=>
int(1)
[1]=>
string(6) "route0"
[2]=>
array(1) {
["name"]=>
string(4) "gallu"
}
["request"]=>
array(2) {
[0]=>
string(3) "GET"
[1]=>
string(35) "http://dev.example.com:8080/hello/gallu"
}
}
ãµãâ¦â¦ããããäºæ³è¾¼ã¿ãªãã ãã©
ã»ã$router->dispatch($request);ãã§ããããããrouteãåã£ã¦ãã
ã»routeArgumentsã«å¼æ°ããããã³ã°ãã¦ã(å¤åãå®åããé¢æ°ã®ç¬¬ä¸å¼æ°ã«ä½¿ãç¨éãããªãããªã)
ã»$routeInfoã®key: 'request'ã«ãã¡ã½ããåã¨å®éã®URIãä»ã足ã
ã»requestã®Attributeã«ãrouteInfoããä»ããã¤ã³ã¹ã¿ã³ã¹ãcloseãã¦æ¸¡ã(closeãã¦ããã®ã¯withAttribute()ã®ä¸)
ã£ã¦æããã
ã ã¨ããã¨
ã»ãããããªãã¨ã
ã»äºå以ä¸ãããããã¨ã
ã®åããããããèå³ãããªããå®é¨ã
public/index.php
$app = new \Slim\App; $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name\n"); return $response; }); $app->get('/hoge', function (Request $request, Response $response, array $args) { $response->getBody()->write("Hello, hoge\n"); return $response; }); $app->get('/hoge', function (Request $request, Response $response, array $args) { $response->getBody()->write("Hello, hoge2\n"); return $response; });
ã¾ãã¯éè¤ãã¿ã¼ã³ã
ãSlim Application Errorãããããããã£ã¤ãã¨ã©ã¼ï½
Message: Cannot register two routes matching "/hoge" for method "GET"
File: /home/gallu/slim_test_plain/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php
Line: 86
Trace: #0 /home/gallu/slim_test_plain/vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php(30): FastRoute\DataGenerator\RegexBasedAbstract->addStaticRoute('GET', Array, 'route2')
#1 /home/gallu/slim_test_plain/vendor/nikic/fast-route/src/RouteCollector.php(44): FastRoute\DataGenerator\RegexBasedAbstract->addRoute('GET', Array, 'route2')
#2 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/Router.php(227): FastRoute\RouteCollector->addRoute(Array, '/hoge', 'route2')
#3 /home/gallu/slim_test_plain/vendor/nikic/fast-route/src/functions.php(25): Slim\Router->Slim\{closure}(Object(FastRoute\RouteCollector))
#4 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/Router.php(238): FastRoute\simpleDispatcher(Object(Closure), Array)
#5 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/Router.php(191): Slim\Router->createDispatcher()
#6 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/App.php(582): Slim\Router->dispatch(Object(Slim\Http\Request))
#7 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/App.php(506): Slim\App->dispatchRouterAndPrepareRoute(Object(Slim\Http\Request), Object(Slim\Router))
#8 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/MiddlewareAwareTrait.php(117): Slim\App->__invoke(Object(Slim\Http\Request), Object(Slim\Http\Response))
#9 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/App.php(405): Slim\App->callMiddlewareStack(Object(Slim\Http\Request), Object(Slim\Http\Response))
#10 /home/gallu/slim_test_plain/vendor/slim/slim/Slim/App.php(314): Slim\App->process(Object(Slim\Http\Request), Object(Slim\Http\Response))
#11 /home/gallu/slim_test_plain/public/index.php(24): Slim\App->run()
#12 {main}
View in rendered output by enabling the "displayErrorDetails" setting.
ãµã
vendor/nikic/fast-route/src/DataGenerator/RegexBasedAbstract.php
private function addStaticRoute($httpMethod, $routeData, $handler) { $routeStr = $routeData[0]; if (isset($this->staticRoutes[$httpMethod][$routeStr])) { throw new BadRouteException(sprintf( 'Cannot register two routes matching "%s" for method "%s"', $routeStr, $httpMethod )); }
ãããã
ã¨ããããã¬ã¼ãããã¦ããäºãããã£ãã®ã§å®å¿ã
ãªãã£ãå ´åã
array(1) {
[0]=>
int(0)
}
array(2) {
[0]=>
int(0)
["request"]=>
array(2) {
[0]=>
string(3) "GET"
[1]=>
string(28) "http://dev.example.com:8080/foo"
}
}
ããrouteã空ã®ã¾ã¾ãªã®ããäºè§£ã
ãã§ãæ¹ãã¦æ¬¡ã
vendor/slim/slim/Slim/App.php
__invoke()ã®
if ($routeInfo[0] === Dispatcher::FOUND) { $route = $router->lookupRoute($routeInfo[1]); return $route->run($request, $response); } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) { if (!$this->container->has('notAllowedHandler')) { throw new MethodNotAllowedException($request, $response, $routeInfo[1]); } /** @var callable $notAllowedHandler */ $notAllowedHandler = $this->container->get('notAllowedHandler'); return $notAllowedHandler($request, $response, $routeInfo[1]); }
ãã®è¾ºã
å
ã«æ°ã«ãªã£ããã§Dispatcher::FOUNDã確èª
int(1)
ã»ãã
ãªãã¨ãªããisset($routeInfo[1])ãã§ãããããããï¼ ã¨ãæããªãããªããã©ãã¾ãæ°ã«ããªããâ¦â¦â¦ãã¡ãããããããªããã以å¤ã®statusãããã½ããã
æ°ã«ãªã£ãã®ããDispatcher::METHOD_NOT_ALLOWEDãã
ã¡ãªã¿ã«å¤ãã®ãã®ã¯ãint(2)ãã
methodã ããªããã§ãå¯è½æ§ã
public/index.php
$app = new \Slim\App; $app->get('/hello/{name}', function (Request $request, Response $response, array $args) { $name = $args['name']; $response->getBody()->write("Hello, $name\n"); return $response; }); $app->post('/hoge', function (Request $request, Response $response, array $args) { $response->getBody()->write("Hello, hoge\n"); return $response; });
vendor/slim/slim/Slim/App.php
if ($routeInfo[0] === Dispatcher::FOUND) { $route = $router->lookupRoute($routeInfo[1]); return $route->run($request, $response); } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) { echo "Trap 1\n"; if (!$this->container->has('notAllowedHandler')) { echo "Trap 2\n"; exit; throw new MethodNotAllowedException($request, $response, $routeInfo[1]); } /** @var callable $notAllowedHandler */ $notAllowedHandler = $this->container->get('notAllowedHandler'); echo "Trap 3\n"; var_dump($notAllowedHandler); exit; return $notAllowedHandler($request, $response, $routeInfo[1]); }
Trap 1
Trap 3
object(Slim\Handlers\NotAllowed)#40 (1) {
["knownContentTypes":protected]=>
array(4) {
[0]=>
string(16) "application/json"
[1]=>
string(15) "application/xml"
[2]=>
string(8) "text/xml"
[3]=>
string(9) "text/html"
}
}
ãµãã
ã»$this->container->has('notAllowedHandler')ãã¯ãããã©ã«ãã§ä½ã£ã¦ãã¨æããããã¾ãæ®éã¯true
ã»Slim\Handlers\NotAllowedã¯ã©ã¹ãcall
ã¦ãªæããã
軽ã Slim\Handlers\NotAllowed ã確èªã
vendor/slim/slim/Slim/Handlers/NotAllowed.php
ãµãâ¦â¦â¦renderHtmlNotAllowedMessage()ã«HTMLãç´æ¸ããããã®ãã
ã¾ãæ®éã«ç´å¾ãã©ãã«ããããã
ã»ç¶æ¿ãã¦renderHtmlNotAllowedMessage()ã¡ã½ããä¸æ¸ã
ã»containerã«çªã£è¾¼ã¿ãªãã
ã§ããã ãããã
ã¤ãã§ã«
vendor/slim/slim/Slim/Handlers/NotFound.php
ãã大ä½ãåãä½ãã ããããããï½ï½ï½
æ¬é¡ã«æ»ãã¦ã
ã»URIã«ã¼ãã£ã³ã°ããããã©methodã¡ãããããªå¦ç
ã¯è¦ããã
ãã®æ¬¡ãè¦ã¤ãããªãã¨ããã¿ã¼ã³ã ãã
if (!$this->container->has('notFoundHandler')) { throw new NotFoundException($request, $response); } /** @var callable $notFoundHandler */ $notFoundHandler = $this->container->get('notFoundHandler'); return $notFoundHandler($request, $response);
大ã¾ãã«ã¯
ã»$this->container->has('notFoundHandler') ãªããªãããã©ã®NotFoundExceptionãã§ãã¾ãããããã
ã»ã³ã³ããã«ããããªãããã¤ä½¿ãã vendor/slim/slim/Slim/Handlers/NotFound.php ã ã¹ã
ã£ã¦æãã
ãã¦ãå ¨ã¦ã®æèãåãåã£ã¦ãæ¬ä¸¸ä¸ã®æ¬ä¸¸
if ($routeInfo[0] === Dispatcher::FOUND) { $route = $router->lookupRoute($routeInfo[1]); return $route->run($request, $response); } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
ããã®ãtrueã®å¦çã
ã¨ãããã
$route
$route->run
ãæ°ã«ãªãã®ã§å¼ã£å¼µãåºãã¦ã¿ãã
$routeã¯ã¾ãå½ç¶ã®ãã¨ããobject(Slim\Route)ãã
ãã§ã¯ãrunã¡ã½ãããç´è§£ãã¦ã¿ã¾ããã
vendor/slim/slim/Slim/Route.php
public function run(ServerRequestInterface $request, ResponseInterface $response) { // Finalise route now that we are about to run it $this->finalize(); // Traverse middleware stack and fetch updated response return $this->callMiddlewareStack($request, $response); }
ããã·ã³ãã«ã
public function finalize() { if ($this->finalized) { return; } $groupMiddleware = []; foreach ($this->getGroups() as $group) { $groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware); } $this->middleware = array_merge($this->middleware, $groupMiddleware); foreach ($this->getMiddleware() as $middleware) { $this->addMiddleware($middleware); } $this->finalized = true; }
ãµãâ¦â¦â¦ã¨ãããã¨ã¯ã
var_dump( $this->finalized ); $this->finalize(); var_dump( $this->finalized ); exit;
bool(false)
bool(true)
ããäºæ³éãããäºéã«éãã®ãé²ãã§ããæããã
åæå¤
private $finalized = false;
ãããªãã ããã
middlewareã¯ãå¤åä»ã¯è¨å®ãã¦ãªããããªãã
$groupMiddleware = []; foreach ($this->getGroups() as $group) { echo "groupMiddleware\n"; $groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware); } $this->middleware = array_merge($this->middleware, $groupMiddleware); foreach ($this->getMiddleware() as $middleware) { echo "addMiddleware\n"; $this->addMiddleware($middleware); } exit;
ããåºåãããªãã
ã¾ãããã¯ä¸æ¦æ¾ç½®ãã§ã
æ»ã£ã¦ãrun()ã
// Traverse middleware stack and fetch updated response return $this->callMiddlewareStack($request, $response);
ããããã
â¦â¦â¦ããããªãã
ç¶æ¿å
ï¼ useï¼
use MiddlewareAwareTrait;
vendor/slim/slim/Slim/MiddlewareAwareTrait.php
public function callMiddlewareStack(ServerRequestInterface $request, ResponseInterface $response) { if (is_null($this->tip)) { $this->seedMiddlewareStack(); } /** @var callable $start */ $start = $this->tip; $this->middlewareLock = true; $response = $start($request, $response); $this->middlewareLock = false; return $response; }
ãã£ããã£ãã
â¦â¦â¦ãããªããè¦ããªããããããã«æ»ã£ã¦ããã®ãã
ãµãâ¦â¦â¦å®é¨â¦â¦â¦ã®åã«ããã¬å®é¨ã
$obj = new stdClass(); $obj2 = new stdClass(); var_dump( spl_object_hash($obj), $obj ); var_dump( spl_object_hash($obj2), $obj2 );
string(32) "000000003df3aa3d0000000044a939ab"
object(stdClass)#1 (0) {
}
string(32) "000000003df3aa3e0000000044a939ab"
object(stdClass)#2 (0) {
}
æªããã¨ã¯è¨ããããã¡ãã£ã¨ã軽ãä¸ç®ã§æ¯è¼ãããã«ã¯ãé¢åã ãªããä¸è¿°ã ã£ã¦ã32æåä¸ã31æåãä¸ç·ãã¨ããä½ã®ééãæ¢ãã ãï½
$obj = new stdClass(); $obj2 = new stdClass(); var_dump( spl_object_id($obj), $obj ); var_dump( spl_object_id($obj2), $obj2 );
int(1)
object(stdClass)#1 (0) {
}
int(2)
object(stdClass)#2 (0) {
}
ãããã£ã¡ã®ã»ããé²è¦§æ§ããããã
ãã ããªãã§ããspl_object_idã£ã¦ã(PHP 7 >= 7.2.0)ããªã®ã§ãã注æã®ã»ã©ãã
æ®éã«ã5.3ç³»ãããããå±
座ã£ã¦ããããããªããã ããã«ããã
ã§ãæ¬é¡ã«æ»ãã¦ã
callMiddlewareStackããã©ã¼ãã¼é¢¨ã«(誰ãããã©ããª$thisã®æèã§)ãcallããã¦ããã確èªã
vendor/slim/slim/Slim/MiddlewareAwareTrait.php
public function callMiddlewareStack(ServerRequestInterface $request, ResponseInterface $response) { var_dump( get_class($this) ); var_dump( spl_object_id($this) );
string(8) "Slim\App"
int(3)
string(10) "Slim\Route"
int(21)
ã¾ãobject_idåãã¾ã§ããªãã£ããããã£ã¦ã®ã¯ç½®ãã¨ãã¦ã
ã»ååã¯App
ã»æ¬¡åã¯Route
ããå¼ã°ãã¦ããä½ã¨ãªã
ã»ååã¯ãå
¨ä½ããããï¼ã¤ã®Routeãé¸ã¶ãããã«æµãã¦
ã»æ¬¡åã¯ãå¦çã®æ¬ä¸¸ãæµããããã«æµãã
ã®ããªãï¼
ãªãã§å
±éã«ãã¦ããã®ããã¯ãè¬ã
ã¾ããå¿ãããªããRouteã®__invokeããè¦ã¦ã¿ã¾ããã
â¦â¦â¦ãããã«é·ããªã£ã¦ããã®ã§ã次åã