$segment !== ''); foreach ($segments as $segment) { if ($segment === '.' || $segment === '..') { return null; } } return '/'.implode('/', $segments); } /** @return list */ public static function tenantKeyCandidates(mixed $domain, mixed $path): array { $host = self::normalize($domain); if ($host === null) { return []; } return array_map( static fn (string $basePath): string => $host.($basePath === '/' ? '' : $basePath), self::basePathCandidates($path), ); } /** @return list */ public static function basePathCandidates(mixed $path): array { $normalizedPath = self::normalizePath($path); if ($normalizedPath === null) { return []; } $segments = array_values(array_filter( explode('/', $normalizedPath), static fn (string $segment): bool => $segment !== '', )); $candidates = []; while ($segments !== []) { $candidates[] = '/'.implode('/', $segments); array_pop($segments); } $candidates[] = '/'; return $candidates; } }