php slimで routingが正しくどうなっているかログを仕込む

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];
    }

```