Handles routing information received from the rewrite engine

@param string $uri
@param string $method

@return \ManaPHP\RouterContext|false
423704
public function match($uri = null, $method = null)
    {
        $context = $this->_context;

        $uri = $uri ?: $this->getRewriteUri();

        if ($method === null) {
            $method = $this->request->getServer('REQUEST_METHOD');
        }

        $context->controller = null;
        $context->action = null;
        $context->params = [];

        $context->matched = false;

        if ($this->_prefix) {
            if (strpos($uri, $this->_prefix) === 0) {
                $handledUri = substr($uri, strlen($this->_prefix)) ?: '/';
            } else {
                $handledUri = false;
            }
        } else {
            $handledUri = $uri;
        }

        $area = null;
        $routes = $this->_simple_routes;
        if ($handledUri === false) {
            $parts = false;
        } elseif (isset($routes[$method][$handledUri])) {
            $parts = $routes[$method][$handledUri]->match($handledUri, $method);
        } elseif (isset($routes[''][$handledUri])) {
            $parts = $routes[''][$handledUri]->match($handledUri, $method);
        } else {
            $parts = false;
            $routes = $this->_regex_routes;
            for ($i = count($routes) - 1; $i >= 0; $i--) {
                $route = $routes[$i];
                if (($parts = $route->match($handledUri, $method)) !== false) {
                    if ($handledUri !== '/' && $this->_areas) {
                        if (($pos = strpos($handledUri, '/', 1)) === false) {
                            $area = Text::camelize(substr($handledUri, 1));
                        } else {
                            $area = Text::camelize(substr($handledUri, 1, $pos - 1));
                        }

                        if (!in_array($area, $this->_areas, true)) {
                            $area = null;
                        }
                    }
                    break;
                }
            }

            if ($parts === false) {
                if ($handledUri !== '/' && $this->_areas) {
                    if (($pos = strpos($handledUri, '/', 1)) !== false) {
                        $area = Text::camelize(substr($handledUri, 1, $pos - 1));
                        if (in_array($area, $this->_areas, true)) {
                            $handledUri = substr($handledUri, $pos);
                        } else {
                            $area = null;
                        }
                    } else {
                        $area = Text::camelize(substr($handledUri, 1));
                        if (in_array($area, $this->_areas, true)) {
                            $handledUri = '/';
                        } else {
                            $area = null;
                        }
                    }
                }

                $handledUri = $handledUri === '/' ? '/' : rtrim($handledUri, '/');
                $parts = $this->_default_route->match($handledUri, $method);
            }
        }

        if ($parts === false) {
            return false;
        }

        $context->matched = true;

        if ($area) {
            $context->area = $area;
        } elseif (isset($parts['area'])) {
            $context->area = $parts['area'];
        }

        $context->controller = $parts['controller'];
        $context->action = $parts['action'];
        $context->params = isset($parts['params']) ? $parts['params'] : [];

        return $context;
    }
1248846
private function addRoute($uri, $method, $callback, $settings)
    {
        $groupItem = count($this->groups) - 1;
        $group = '';
        if ($groupItem > -1) {
            foreach ($this->groups as $key => $value) {
                $group .= $value['route'];
            }
        }

        $page = dirname($_SERVER['PHP_SELF']);
        $page = $page === '/' ? '' : $page;
        if (strstr($page, 'index.php')) {
            $data = implode('/', explode('/', $page));
            $page = str_replace($data, '', $page);
        }

        $route = $page . $group . '/' . trim($uri, '/');
        $route = rtrim($route, '/');
        if ($route === $page) {
            $route .= '/';
        }

        $data = [
            'route' => str_replace('//', '/', $route),
            'method' => strtoupper($method),
            'callback' => $callback,
            'name' => (isset($settings['name'])
                ? $settings['name']
                : null
            ),
            'before' => (isset($settings['before'])
                ? $settings['before']
                : null
            ),
            'after' => (isset($settings['after'])
                ? $settings['after']
                : null
            ),
            'group' => ($groupItem === -1) ? null : $this->groups[$groupItem]
        ];
        array_push($this->routes, $data);
    }
1001429
public function dispatch($method, $uri)
	{
	    $this->loadDefaultRoutes();
	    
	    $routeArguments = [];
	    
		// strip base url
		if (strpos($_SERVER['SCRIPT_NAME'], $uri) === 0) {
		    $uri = '/';
		} else {
		    $uri = str_replace($_SERVER['SCRIPT_NAME'], '', $uri);
            $uri = '/' . trim($uri, '/');
            
            // separate uri to uri and params
            $params = [];
            if (strpos($uri, '/p/')) {
                $parts = explode('/p/', $uri, 2);
                $uri = $parts[0];
                $params = $parts[1];
            } elseif (strpos($uri, '&')) {
                $parts = explode('&', $uri, 2);
                $uri = $parts[0];
                $params = $parts[1];
            }
            
            if ($params) {
                $routeArguments = UriHelper::parseQueryFromPath($params);
            }
		}
		
		/**
		 * @var array $routeInfo
		 * [0]  not found
		 * [1, $routeIndentifier, [GET, $request_uri]] found 
		 * [2, ['GET', 'OTHER_ALLOWED_METHODS']] not allowed
		 * 
		 * @link   https://github.com/nikic/FastRoute/blob/master/src/Dispatcher.php
		 */
		$routeInfo = $this->createDispatcher()->dispatch($method, $uri);
		
		$result = new DispatchResult();
		$result->flag = $routeInfo[0];
		
		if ($routeInfo[0] === Dispatcher::FOUND) {
			$route = $this->lookupRoute($routeInfo[1]);
			
			foreach ($routeInfo[2] as $k => $v) {
				$routeArguments[$k] = urldecode($v);
			}
			$route->setArguments($routeArguments);
			
			$result->route = $route;
		} elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
			$result->info = $routeInfo[RouterInterface::ALLOWED_METHODS];
		}
		//print_r($this->getRoutesPatterns()); print_r($result); exit;
		
		return $result;
	}
1098393
protected function addRoute($method, $uri, $action)
    {
        $uri = '/'.trim($uri, '/');
        if (is_string($action)) {
            $action = ['uses' => $action];
        }

        if (! is_array($action) || empty($action['uses']) || ! is_string($action['uses'])) {
            throw new \Exception('错误的路由' . $uri);
        }

        $this->routeCollector->addRoute($method, $uri, $action);
    }
1115360
public function addRoute($method, $uri, $action)
    {
        $uri = strtolower($uri);
        $action = $this->parseAction($action);

        if (isset($this->groupAttributes)) {
            if (isset($this->groupAttributes['prefix'])) {
                $uri = trim($this->groupAttributes['prefix'], '/').'/'.trim($uri, '/');
            }

            $action = $this->mergeGroupAttributes($action);
        }

        $uri = '/'.trim($uri, '/');

        if (isset($action['as'])) {
            $this->namedRoutes[$action['as']] = $uri;
        }

        $this->routes[$this->identifier] = ['method' => $method, 'uri' => $uri, 'action' => $action];
        $this->identifier++;

        return $this;
    }
366485
public function dispatch($uri = null, $method = null)
    {
        if (!$router_context = $this->match($uri, $method)) {
            throw new NotFoundRouteException(['router does not have matched route for `:uri`', 'uri' => $this->getRewriteUri()]);
        }

        return $this->dispatcher->dispatch($router_context);
    }
1325989
protected function makeRequest($method, $uri, $options)
    {
        $logger = $this->getLogger();

        try {
            $logger->info(sprintf('Making API %s request to %s', $method, $uri), [$options]);

            /** @var ResponseInterface $response */
            $response = $this->_doRequest($method, $uri, $options);

            $logger->debug('Response from HTTP call was status code:', [$response->getStatusCode()]);
            $logger->debug('Response JSON was:', [$response->getBody()]);

            return $response;
        } catch (\Exception $e) {
            throw $e; // Just rethrow for now
        }
    }
884176
public function createRequest($method, $uri)
    {
        if (is_string($uri)) {
            $uri = (new UriFactory())->createUri($uri);
        }
        return new Request($method, $uri);
    }
913867
public function request($method, $uri, array $parameters = [])
    {
        return $this->container->get(AdapterInterface::class)
            ->request($method, $uri, $parameters);
    }
838375
public function match($methods, $uri, $action)
    {
        return $this->addRoute(\array_map('strtoupper', (array) $methods), $uri, $action);
    }
477680
public function addRoute($method, $uri, callable $handler, $hooks=[])
    {
        $this->routes[] = [$method, $uri, $handler, $hooks];
    }
1101253
public function forward($uri, $method = Request::METHOD_GET)
    {
        if ('cli' === PHP_SAPI) {
            throw new BaseException('You can not call forward method in cli mode.');
        }

        $request = $this->getRequest()->withMethod($method);

        $this->getContainer()->setShared('request', $request);

        $oldRouter = $this->getRouter();

        $oldRequestUri = $_SERVER['REQUEST_URI'];
        $oldGetUrl = $_GET['_url'];
        $_GET['_url'] = $_SERVER['REQUEST_URI'] = $uri;
        $this->getContainer()->setShared('router', new Router());
        $this->getRouter()->setPrefix($oldRouter->getPrefix());
        $this->getRouter()->handle($uri);

        $dispatcher = new Dispatcher();
        $response = $dispatcher->setAction($this->getRouter()->getAction())
            ->setActionNamespace($this->getRouter()->getActionNamespace())
            ->setBundle($this->getRouter()->getBundle())
            ->setParams($this->getRouter()->getParams())
            ->setResponderNamespace($this->getRouter()->getResponderNamespace())
            ->setRouteMatched($this->getRouter()->isMatched())
            ->dispatch($request);

        // restore latest state
        $this->getContainer()->setShared('router', $oldRouter);
        $_SERVER['REQUEST_URI'] = $oldRequestUri;
        $_GET['_url'] = $oldGetUrl;

        return $response;
    }
242524
public function addRoute($method, $uri, $action)
    {
        $action = $this->parseAction($action);

        $attributes = null;

        if ($this->hasGroupStack()) {
            $attributes = $this->mergeWithLastGroup([]);
        }

        if (isset($attributes) && \is_array($attributes)) {
            if (isset($attributes['prefix'])) {
                $uri = \trim($attributes['prefix'], '/').'/'.\trim($uri, '/');
            }

            if (isset($attributes['suffix'])) {
                $uri = \trim($uri, '/').\rtrim($attributes['suffix'], '/');
            }

            $action = $this->mergeGroupAttributes($action, $attributes);
        }

        $uri = '/'.\trim($uri, '/');

        if (isset($action['as'])) {
            $this->namedRoutes[$action['as']] = $uri;
        }

        if (\is_array($method)) {
            foreach ($method as $verb) {
                $this->routes[$verb.$uri] = ['method' => $verb, 'uri' => $uri, 'action' => $action];
            }
        } else {
            $this->routes[$method.$uri] = ['method' => $method, 'uri' => $uri, 'action' => $action];
        }
    }
108175
public function matchUrl($method, $url) {
		if ($this->method == $method) {
			if (preg_match('/^' . $this->url . '$/', $url, $matches)) {
				$params = $this->prepareParams($matches);
				$this->execute($params);
				return true;
			}
			return false;
		}
	}
94729
public function addRoute(array $method, string $uri, $action): Route {
        if (is_string($action)) {
            $action = $this->addPackage($action);
        }
        $uri = $this->addPrefix($uri);
        $route = new Route($uri, is_callable($action) ? $action : function() use ($action) {
            return $this->makeResponse($action);
        }, $method, $this->globalFilters);
        foreach ($route->getMethods() as $item) {
            $this->staticRouteMap[$item][$uri] = $route;
        }
        return $route;
    }
809097
private function requestHub($method, $uri, $options)
    {
        try {
            if ($this->getAsync()) {
                return $this->client->requestAsync($method, $uri, $options);
            }

            return $this->client->request($method, $uri, $options);
        } catch (ConnectException $e) {
            if ($options['retries'] > 0) {
                --$options['retries'];

                return $this->requestHub($method, $uri, $options);
            }

            throw new ConnectException($e->getMessage(), $e->getRequest(), null, $e->getHandlerContext());
        }
    }
381374
private function checkMatches(string $uri, string $method): array
    {
        return array_map(
            function($regexp, $route) use ($uri, $method) {
                $match = preg_match_all($regexp, $uri, $matches);

                // If something found and method is correct
                if ($match && $route->checkMethod($method)) {
                    // Set array of variables
                    $route->setVariables($matches);
                    return $route;
                }
                return null;
            },
            // Array with keys
            $this->getRoutes(true),
            // Array with values
            $this->getRoutes()
        );
    }