如何获得反向路由?

时间:2016-09-01 15:35:58

标签: php

我在路由配置中有规则

/**
 * Format
 * [controller, action($id,...), module]
 *
 * s: - string
 * i: - integer
 * {placeholder} - for replace in URL
 */
$rules = [
    '/' => ['site', 'index'],
    '/[s:action]' => ['site', '{action}'],
    '/[s:action]/[s:controller]' => ['{controller}', '{action}'],
    '/[s:module]/[s:controller]/[i:id]' => ['{controller}', 'view', '{module}'],
    '/[s:module]/[s:controller]/[s:action]/[i:id]' => ['{controller}', '{action}', '{module}'],
    '/[s:controller]/[i:id]/[i:id2]/[i:id3]' => ['{controller}', 'parse'],
];

如何获得反向路由?

//Full URL => Rewrite URL 
$results = [
    '/' => '/',
    'site/index' => '/',
    'site/login' => '/login',
    'info/user' => '/user/info',
    'user/profile/view/123' => '/user/profile/123',
    'user/profile/edit/123' => '/user/profile/edit/123',
];

如何正确地做到最佳性能?

更新这是路由代码 对于上一步中的解析模式。 据我所知,将其视为模板和路由参数,以形成最终路径。

function checkRule($path, $pattern) {
    $params = [];

    if ($pattern === '*') {
        //Everyone
        $match = true;
    } elseif (isset($pattern[0]) && $pattern[0] === '@') {
        //Custom regexp
        $pattern = '`' . substr($pattern, 1) . '`u';
        $match = preg_match($pattern, $path, $params);
    } else {
        //Parse pattern
        $n = isset($pattern[0]) ? $pattern[0] : null;
        $route = null;
        $regex = false;
        $j = 0;
        $i = 0;

        // Find the longest non-regex substring and match it against the URI
        while (true) {
            if (!isset($pattern[$i])) {
                break;
            }

            if (false === $regex) {
                $c = $n;
                $regex = $c === '[' || $c === '(' || $c === '.';

                if (false === $regex && false !== isset($pattern[$i + 1])) {
                    $n = $pattern[$i + 1];
                    $regex = $n === '?' || $n === '+' || $n === '*' || $n === '{';
                }

                if (false === $regex && $c !== '/' && (!isset($path[$j]) || $c !== $path[$j])) {
                    return null;
                }

                $j++;
            }

            $route .= $pattern[$i++];
        }

        $regex = self::compileRoute($route);
        $match = preg_match($regex, $path, $params);
    }

    if ($match) {
        return $params;
    }

    return null;
}


function compileRoute($route) {
    if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
        $matchTypes = self::$matchTypes;

        foreach ($matches as $match) {
            list($block, $pre, $type, $param, $optional) = $match;

            if (isset($matchTypes[$type])) {
                $type = $matchTypes[$type];
            }

            if ($pre === '.') {
                $pre = '\.';
            }

            if ($param !== '') {
                $param = "?P<{$param}>";
            }

            if ($optional !== '') {
                $optional = '?';
            }

            $pattern = "(?:{$pre}({$param}{$type})){$optional}";
            $route = str_replace($block, $pattern, $route);
        }
    }

    return "`^{$route}$`u";
}

0 个答案:

没有答案