PHPでAPIサーバーを実装仕様として、slim frameworkを試すことにしました。
500エラーが出ているのだけど、ログを仕込んでもでてこない。
おそらく、routingが失敗しているのかな。。
と言うことで、routingの確認のログを仕込んでみました。
slim本体に手を入れることになるので、備忘録方々メモします
slim は v4です https://www.slimframework.com/docs/v4/
vendor/slim/Slim/Middleware.php を見る
- $app = AppFactory::create();
- $app->addRoutingMiddleware();
で、利用されるのが、上の Middleware.php になります
この中で、渡された urlからroutingを決めるのがこの部分
protected function resolveRoutingResultsFromRequest(ServerRequestInterface $request): RoutingResults
{
return $this->routeResolver->computeRoutingResults(
$request->getUri()->getPath(),
$request->getMethod()
);
}
この routeResolver は vendor/slim/slim/Slim/interfaces/RouteResolverInterface.php なのですが、実体は
vendor/slim/slim/Slim/Routing/RouteResolver.php になります
public function computeRoutingResults(string $uri, string $method): RoutingResults
{
$uri = rawurldecode($uri);
if ($uri === '' || $uri[0] !== '/') {
$uri = '/' . $uri;
}
return $this->dispatcher->dispatch($method, $uri);
}
とたどっていくと、最終的に行き着くのが
vendor/slim/slim/Slim/Routing/FastRouteDispatcher.php
error_logを使って調べました
private function routingResults(string $httpMethod, string $uri): array
{
if (isset($this->staticRouteMap[$httpMethod][$uri])) {
error_log(" *** found in staticRouteMap "
.$this->staticRouteMap[$httpMethod][$uri], 0);
return [self::FOUND, $this->staticRouteMap[$httpMethod][$uri], []];
}
if (isset($this->variableRouteData[$httpMethod])) {
$result = $this->dispatchVariableRoute($this->variableRouteData[$httpMethod], $uri);
error_log(" *** found in variableRouteaData ".print_r($result, true),
0);
if ($result[0] === self::FOUND) {
return [self::FOUND, $result[1], $result[2]];
}
}
// error_log(" **staticRouteMap".print_r($this->staticRouteMap,true),0);
// error_log(" **variableRoute ".var_export($this->variableRouteData,true),0);
return [self::NOT_FOUND, null, []];
}
具体的に呼び出すのは
vendor/slim/slim/Slim/Routing/Route.phpの handleと言う部分
public function handle(ServerRequestInterface $request): ResponseInterface
{
if ($this->callableResolver instanceof AdvancedCallableResolverInterface) {
$callable = $this->callableResolver->resolveRoute($this->callable);
} else {
$callable = $this->callableResolver->resolve($this->callable);
}
$strategy = $this->invocationStrategy;
error_log("** routing found3: ".print_r($callable,
true),0);
/** @var string[] $strategyImplements */
$strategyImplements = class_implements($strategy);
if (
is_array($callable)
&& $callable[0] instanceof RequestHandlerInterface
&& !in_array(RequestHandlerInvocationStrategyInterface::class, $strategyImplements)
) {
$strategy = new RequestHandler();
}
$response = $this->responseFactory->createResponse();
return $strategy($callable, $request, $response, $this->arguments);
}
今の調査だと、ここの "** routing found3: "と言うのが呼び出されていないのがわかりました。
Slimの Routerがどの様に関数を呼び出すのか?
この部分になります
vendor/slim/slim/Slim/CallableResolver.php
private function resolveSlimNotation(string $toResolve): array
{
preg_match(CallableResolver::$callablePattern, $toResolve, $matches);
[$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null];
if ($this->container && $this->container->has($class)) {
$instance = $this->container->get($class);
} else {
if (!class_exists($class)) {
throw new RuntimeException(sprintf('Callable %s does not exist', $class));
}
$instance = new $class($this->container);
}
return [$instance, $method];
}
こんな感じで、ログを出力する事で原因がやっとわかりました。参考までに
private function resolveSlimNotation(string $toResolve): array
{
error_log( " ** ".__FUNCTION__." ".$toResolve." ".__FILE__."(".__LINE__.")",0);
preg_match(CallableResolver::$callablePattern, $toResolve, $matches);
[$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null];
try {
if ($this->container && $this->container->has($class)) {
$instance = $this->container->get($class);
} else {
if (!class_exists($class)) {
throw new RuntimeException(sprintf('Callable %s does not exist', $class));
}
$instance = new $class($this->container);
}
} catch (\Throwable $e){
error_log( " ** ".__FUNCTION__." ".$e->getMessage()." ".__FILE__."(".__LINE__.")",0);
throw $e;
}
return [$instance, $method];
}