匹配路由

@param array $pathInfo

@return mixed
513936
private function isRoute(&$pathInfo)
    {
        empty($pathInfo) && $pathInfo[0] = '/';//网站根地址
        $isSuccess = [];
        $route = self::$rules;

        $httpMethod = isset($_POST['_method']) ? strtoupper($_POST['_method']) : strtoupper($_SERVER['REQUEST_METHOD']);

        switch ($httpMethod) {
            case 'GET':
                $rMethod = self::REQUEST_METHOD_GET;
                break;
            case 'POST':
                $rMethod = self::REQUEST_METHOD_POST;
                break;
            case 'PUT':
                $rMethod = self::REQUEST_METHOD_PUT;
                break;
            case 'PATCH':
                $rMethod = self::REQUEST_METHOD_PATCH;
                break;
            case 'DELETE':
                $rMethod = self::REQUEST_METHOD_DELETE;
                break;
            case 'OPTIONS':
                $rMethod = self::REQUEST_METHOD_OPTIONS;
                break;
            default :
                $rMethod = self::REQUEST_METHOD_ANY;
        }

        foreach ($route as $k => $v) {
            $rulesMethod = substr($k, 0, 1);
            if (
                $rulesMethod != $rMethod
                && $rulesMethod != self::REQUEST_METHOD_ANY
                && $rulesMethod != self::REST_ROUTE
            ) { //此条路由不符合当前请求方式
                continue;
            }
            unset($v);
            $singleRule = substr($k, 1);
            $arr = $singleRule === '/' ? [$singleRule] : explode('/', ltrim($singleRule, '/'));

            if ($arr[0] == $pathInfo[0]) {
                array_shift($arr);
                foreach ($arr as $key => $val) {
                    if (isset($pathInfo[$key + 1]) && $pathInfo[$key + 1] !== '') {
                        if (strpos($val, '\d') && !is_numeric($pathInfo[$key + 1])) {//数字变量
                            $route[$k] = false;//匹配失败
                            break 1;
                        } elseif (strpos($val, ':') === false && $val != $pathInfo[$key + 1]) {//字符串
                            $route[$k] = false;//匹配失败
                            break 1;
                        }
                    } else {
                        $route[$k] = false;//匹配失败
                        break 1;
                    }
                }
            } else {
                $route[$k] = false;//匹配失败
            }

            if ($route[$k] !== false) {//匹配成功的路由
                $isSuccess[] = $k;
            }
        }

        if (empty($isSuccess)) {
            $returnArr[0] = false;
        } else {
            //匹配到多条路由时 选择最长的一条（匹配更精确）
            usort($isSuccess, function ($item1, $item2) {
                return strlen($item1) >= strlen($item2) ? 0 : 1;
            });

            if (is_callable($route[$isSuccess[0]])) {
                \Cml\Route::executeCallableRoute($route[$isSuccess[0]], substr($isSuccess[0], 1));
            }

            is_array($route[$isSuccess[0]]) || $route[$isSuccess[0]] = trim(str_replace('\\', '/', $route[$isSuccess[0]]), '/');

            //判断路由的正确性
            if (!is_array($route[$isSuccess[0]]) && count(explode('/', $route[$isSuccess[0]])) < 2) {
                throw new \InvalidArgumentException(Lang::get('_ROUTE_PARAM_ERROR_', substr($isSuccess[0], 1)));
            }

            $returnArr[0] = true;
            $successRoute = explode('/', $isSuccess[0]);
            foreach ($successRoute as $key => $val) {
                $t = explode('\d', $val);
                if (strpos($t[0], ':') !== false) {
                    $_GET[ltrim($t[0], ':')] = $pathInfo[$key];
                }
                unset($pathInfo[$key]);
            }

            if (substr($isSuccess[0], 0, 1) == self::REST_ROUTE) {
                $actions = explode('/', $route[$isSuccess[0]]);
                $arrKey = count($actions) - 1;
                $actions[$arrKey] = strtolower($httpMethod) . ucfirst($actions[$arrKey]);
                $route[$isSuccess[0]] = implode('/', $actions);
            }

            self::$matchRoute = substr($isSuccess[0], 1);
            $returnArr['route'] = $route[$isSuccess[0]];
        }
        return $returnArr;
    }
220526
private function get_node_path(file_info $fileinfo) {
        $encodedpath = base64_encode(json_encode($fileinfo->get_params()));
        return array(
            'path' => $encodedpath,
            'name' => $fileinfo->get_visible_name()
        );
    }
1148879
protected function getFileInfo($path)
    {
        return [
            'name' => substr($path, strrpos($path, '/') + 1),
            'path' => $path,
            'url'  => $this->getFileUrl($path),
        ];
    }
156177
public function getPathInfo()
	{
		$path = trim($this->uri->getPath(false), '/');
		
		if($this->pathBase == '')
		{
			return $path;
		}
		
		if($path == $this->pathBase)
		{
			return '';
		}
		
		return preg_replace("'^" . preg_quote($this->pathBase, "'") . "/'i", '', $path);
	}
915701
public function isMatched($pathinfo, $index)
    {
        $pathinfo = $this->_urlRewrite($pathinfo);

        if (!empty($pathinfo)) {
            $res = explode('/', $pathinfo);
            $this->_controllerName = empty($res[0]) ? $this->_controllerName : ucfirst($res[0]);
            if (count($res) >= 2) {
                $this->_actionName = empty($res[1]) ? $this->_actionName : $res[1];
            }

            if (count($res) > 2) {
                $this->_pathParams = array_slice($res, 2);
            }
        } else {
            if (defined('FOCUS_DEBUG') && FOCUS_DEBUG) {
                $this->getLogger()->debug('pathinfo is empty');
            }
        }

        // 检查控制器是否存在
        $className = "{$this->_controllerNs}\\{$this->_controllerName}";

        if (class_exists($className)) {

            // 检查方法是否存在，不存则则使用index方法
            if (!method_exists($className, $this->_actionName.'Action')) {
                $this->_actionName = 'index';
                if (defined('FOCUS_DEBUG') && FOCUS_DEBUG) {
                    $this->getLogger()->debug('use default action: indexAction');
                }
            }

            return true;
        }

        return false;
    }
882458
static private function decodeConfig(string $path): ?string
    {
        //如果取不到路由配置,则不对此请求进行解析处理,即保持原样
        $config = configDefault(false, 'router');
        if (!$config) {
            return null;
        }

        // 根据路由配置进行解码,循环每一个配置
        foreach ($config as $key => $case) {
            // 下划线开头的表示配置参数,不是路由
            if (substr($key, 0, 1) == '_') {
                continue;
            }

            // 如果没有设置解码参数
            if (!isset($case['decode']) or !$case['decode']) {
                continue;
            }

            // 取路由配置中的解码参数: 源 正则 和 替换内容
            list ($regular, $replace) = $case['decode'];

            // 如果源 正则匹配,则表明需要使用此规则进行处理
            if (preg_match($regular, $path)) {
                // 如果匹配路由,返回替换后的路由
                return preg_replace($regular, $replace, $path);
            }
        }

        return null;
    }
15185
public function _pathinfo() {

        if(isset($this->server['PATH_INFO'])) {
            return $this->server['PATH_INFO'];
        }

        return str_replace(
            '/index.php',
            '',
            explode('?',$this->uri)[0]
        );


        $inputEncoding = NULL;
        $outputEncoding = NULL;
        //参考Zend Framework对pahtinfo的处理, 更好的兼容性
        $pathInfo = NULL;

        //处理requestUri
        $requestUri   = $this->uri;
        $finalBaseUrl = $this->baseurl;

        // Remove the query string from REQUEST_URI
        if ($pos = strpos($requestUri, '?')) {
            $requestUri = substr($requestUri, 0, $pos);
        }

        if ((NULL !== $finalBaseUrl) && (false === ($pathInfo = substr($requestUri, strlen($finalBaseUrl))))  ) {
            // If substr() returns false then PATH_INFO is set to an empty string
            $pathInfo = '/';
        }
        elseif (NULL === $finalBaseUrl) {
            $pathInfo = $requestUri;
        }

        if ($pathInfo) {
            //针对iis的utf8编码做强制转换
            //参考http://docs.moodle.org/ja/%E5%A4%9A%E8%A8%80%E8%AA%9E%E5%AF%BE%E5%BF%9C%EF%BC%9A%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E8%A8%AD%E5%AE%9A
            if (!empty($inputEncoding) && !empty($outputEncoding) && (stripos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false || stripos($_SERVER['SERVER_SOFTWARE'], 'ExpressionDevServer') !== false) ) {
                if (function_exists('mb_convert_encoding')) {
                    $pathInfo = mb_convert_encoding($pathInfo, $outputEncoding, $inputEncoding);
                }
                else if (function_exists('iconv')) {
                    $pathInfo = iconv($inputEncoding, $outputEncoding, $pathInfo);
                }
            }
        }
        else {
            $pathInfo = '/';
        }

        return '/' . ltrim(urldecode($pathInfo), '/');
    }
150780
public function redirect($pathinfo, $hash = null)
    {
        $uri = is_string($pathinfo) ? $pathinfo : $this->generateUrl($pathinfo);
        if (!headers_sent()) {
            header("Location: $uri");
        } else {
            echo <<<MESSAGE
<!DOCTYPE HTML>
<head>
<meta http-equiv='Refresh' content='0; url={$uri}'><title>HTTP 302</title>
</head><body>
<h1>HTTP 302</h1>
<p>Your browser will be automatically redirected.
<br />If not, please click on next link: <a href="{$uri}">{$uri}</a>.</p>
</body></html>
MESSAGE;
        }
        exit;
    }
491571
public function findValue($path, &$ini)
	{
		$value = false;

		if (array_key_exists($path, $ini)) {
			$value = $ini[$path];
		} else {
			// not in the file, pull out the default
			$value = ini_get($path);
			$ini[$path] = $value;
		}

		return $value;
	}
25863
public function initAll(string $path): PathInfoInterface
    {
        $this->path = $path;
        [$this->wrappers, $this->root, $this->dirs] = $this->getPathParts();
        return $this;
    }
1144450
protected function tokenInfo2Fields(array $tokenInfo)
    {
        $fields = array();
        foreach ($tokenInfo as $variableName => $variableInfo) {
            $fields["token-$variableName"] = $this->get1TokenField($variableName, $variableInfo);
        }
        return $fields;
    }
955963
public function getPathInfo()
    {
        $pathInfo = parent::getPathInfo();
        $pathLength = \strlen($pathInfo);

        if ($pathInfo !== '/' && $pathInfo[$pathLength - 1] === '/'
            && (bool) ConfigQuery::read('allow_slash_ended_uri', false)
        ) {
            if (null === $this->resolvedPathInfo) {
                $this->resolvedPathInfo = substr($pathInfo, 0, $pathLength - 1); // Remove the slash
            }

            $pathInfo = $this->resolvedPathInfo;
        }

        return $pathInfo;
    }
905763
public static function getFilesInfo($path, $ext = null, $recursive = 0, &$list): array
    {
        $path = self::pathFormat($path);

        if (!is_dir($path)) {
            throw new NotFoundException("directory not exists! DIR: $path");
        }

        $ext = \is_array($ext) ? implode('|', $ext) : trim($ext);

        static $id = 0;

        //glob()寻找与模式匹配的文件路径
        foreach (glob($path . '*') as $file) {
            $id++;

            // 匹配文件 如果没有传入$ext 则全部遍历，传入了则按传入的类型来查找
            if (is_file($file) && (!$ext || preg_match("/\.($ext)$/i", $file))) {
                $list[$id] = File::info($file);

                //是否遍历子目录
            } elseif ($recursive) {
                $list = self::getFilesInfo($file, $ext, $recursive, $list);
            }
        }

        return $list;
    }
92160
public function pathinfo(string $path, int $options = null)
    {
        [$scheme, $path] = $this->getSchemeAndHierarchy($path);

        if ($this->normalize || ($scheme && null === $this->normalize)) {
            $path = $this->normalizePathPart($path);
        }

        return $this->pathinfoInternal($scheme, $path, $options);
    }
1191377
public static function pathInfo()
    {
        $scriptName = self::getScriptPreg();
        if($scriptName){
            $url = parse_url(preg_replace('/^'.$scriptName.'/', '', $_SERVER['REQUEST_URI'])); // 支持加public和不加public
            return isset($url['path']) ? $url['path'] : '';
        }else
            return '';
    }
1358022
private function getPropertyValue($valueInfo)
    {
        //属性值类型
        $value=$valueInfo;

        //如果值为数组,则递归创建元素值
        if(is_array($value)){
            $values=[];
            foreach ($value as $k => $v){
                $key=$this->replacePlaceHolder($k);
                $values[$key]=$this->getPropertyValue($v);
            }
            return $values;
        }

        //字符串类型的描述
        if(strtolower($value)=="true"){
            $value=true;
        }else if(strtolower($value)=="false"){
            $value=false;
        }else if(strpos(strtolower($value), "ref:")===0){
            //对象引用,递归创建对象
            $refObjId=substr($value, 4);
            $value=$this->create($refObjId);
        }else{
            $value=$this->replacePlaceHolder($value);
        }
        return $value;
    }
866209
protected function isBlacklisted($pathInfo)
    {
        $pathInfo = ltrim($pathInfo, self::SEPARATOR_PATH);
        foreach ($this->blacklist as $pattern) {
            if (preg_match($pattern, $pathInfo)) {
                return true;
            }
        }

        return false;
    }