windwalker/router

Windwalker 路由包

安装: 3,535

依赖者: 1

建议者: 0

安全: 0

星标: 2

关注者: 4

分支: 0

类型:windwalker-package

3.5.23 2020-10-18 10:15 UTC

README

通过 Composer 安装

将此添加到您的 composer.json 文件中的 require 块。

{
    "require": {
        "windwalker/router": "~3.0"
    }
}

入门指南

use Windwalker\Router\Router;

$router = new Router;

添加路由

use Windwalker\Route\Route;

// Route with name
$router->addRoute(new Route('sakura', 'flower/(id)/sakura', array('_controller' => 'SakuraController')));

// Route without name
$router->addRoute(new Route(null, 'flower/(id)/sakura', array('_controller' => 'SakuraController')));

匹配路由

$route = $router->match('flower/12/sakura');

$variables = $route->getVariables(); // Array([_controller] => SakuraController)

// Use variables
$class = $variables['_controller'];

$controller = new $class;

向路由添加更多选项

路由接口: '($name, $pattern[, $variables = array()][, $allowMethods = array()][, $options = array()])'

$route = new Route(
    'name',
    'pattern/of/route/(id).(format)',

    // Default Variables
    array(
        'id'    => 1,
        'alias' => 'foo-bar-baz',
        'format' => 'html'
    ),

    // Allow methods
    array('GET', 'POST'),

    // Options
    array(
        'host'    => 'windwalker.io',
        'scheme'  => 'http', // Only http & https
        'port'    => 80,
        'sslPort' => 443,
        'requirements' => array(
            'id' => '\d+'
        ),
        'extra' => array(
            '_ctrl' => 'Controller\Class\Name',
        )
    )
);

$router->addRoute($route);

// match routes
$route = $router->match(
    'pattern/of/route/25.html',
    array(
        'host'   => $uri->getHost(),
        'scheme' => $uri->getScheme(),
        'port'   => $uri->getPort()
    )
);

$variables = $route->getVariables();

// Merge these matched variables back to http request
$_REQUEST = array_merge($_REQUEST, $variables);

// Extra is the optional variables but we won't want to merge into request
$extra = $router->getExtra();

print_r($variables);
print_r($extra);

打印结果

Array
(
    [id] => 25
    [alias] => foo-bar-baz
    [format] => html
)

Array(
    [_ctrl] => Controller\Class\Name
)

构建路由

build() 是一个用于生成视图模板路由 uri 的方法。

$router->addRoute(new Route('sakura', 'flower/(id)/sakura', array('_controller' => 'SakuraController')));

$uri = $router->build('sakura', array('id' => 30)); // flower/30/sakura

echo '<a href="' . $uri . '">Link</a>';

快速映射

addMap() 是一个简单的方法,用于快速添加路由,而不需要复杂的选项。

$router->addMap('flower/(id)/sakura', array('_controller' => 'SakuraController', 'id' => 1));

$variables = $router->match('flower/30/sakura');

规则

简单参数

new Route(null, 'flower/(id)-(alias)');

可选参数

单个可选参数

new Route(null, 'flower(/id)');

匹配的路由可以是

flower
flower/25

多个可选参数

new Route(null, 'flower(/year,month,day)');

匹配的路由可以是

flower
flower/2014
flower/2014/10
flower/2014/10/12

匹配的变量将是

Array
(
    [year] => 2014
    [month] => 10
    [day] => 12
)

通配符

// Match 'king/john/troilus/and/cressida'
new Route(null, 'flower/(*tags)');

匹配

Array
(
    [tags] => Array
    (
        [0] => john
        [1] => troilus
        [2] => and
        [3] => cressida
    )
)

匹配器

Windwalker Router 提供了一些匹配器,以不同的方式匹配路由。

顺序匹配器

顺序匹配器使用 顺序搜索方法 来查找路由。这是最慢的匹配器,但可以自定义得更多。它是 Windwalker Router 的默认匹配器。

use Windwalker\Router\Matcher\SequentialMatcher;

$router = new Router(array(), new SequentialMatcher);

二分匹配器

二分匹配器使用 二分搜索算法 来查找路由。这个匹配器比顺序匹配器快,但它会破坏路由的顺序。二分搜索会将所有路由按照模式字符重新排序。

use Windwalker\Router\Matcher\BinaryMatcher;

$router = new Router(array(), new BinaryMatcher);

前缀树匹配器

前缀树匹配器使用 前缀树 来搜索路由。这是 Windwalker Router 中最快的方法,但限制是它必须使用更简单的路由模式,这不如其他两个匹配器灵活。

use Windwalker\Router\Matcher\TrieMatcher;

$router = new Router(array(), new TrieMatcher);

前缀树匹配器的规则

简单参数

只有当 uri 段全部存在时才匹配。如果您想使用可选段,您必须添加两个或更多模式。

flower
flower/:id
flower/:id/:alias

通配符

此模式将 flower/ 之后的段转换为名为 tags 的数组

flower/*tags

单动作路由器

单动作路由器是一个简单的路由器,它扩展了 Windwalker Router。如果匹配,它仅返回一个字符串。

这是一个单动作控制器示例

$router->addMap('flower/(id)/(alias)', 'FlowerController');

$controller = $router->match('flower/25/sakura');

$_REQUEST = array_merge($_REQUEST, $router->getVariables());

echo (new $controller)->execute();

或具有动作名称的控制器

$router->addMap('flower/(id)/(alias)', 'FlowerController::indexAction');

$matched = $router->match('flower/25/sakura');

$_REQUEST = array_merge($_REQUEST, $router->getVariables());

list($controller, $action) = explode('::', $matched);

echo (new $controller)->$action();

RestRouter

RestRouter 是一个扩展到 SingleActionRouter 的简单路由器,它可以添加不同方法的某些后缀。

$router->addMap('flower/(id)/(alias)', 'Flower\\Controller\\');

$controller = $router->match('flower/25/sakura', 'POST'); // Get Flower\\Controller\\Create

(new $controller)->execute();

默认后缀映射是

'GET'     => 'Get',
'POST'    => 'Create',
'PUT'     => 'Update',
'PATCH'   => 'Update',
'DELETE'  => 'Delete',
'HEAD'    => 'Head',
'OPTIONS' => 'Options'

您可以覆盖它

$router->setHttpMethodSuffix('POST', 'SaveController');

异常

如果 Router 没有匹配任何内容,它将抛出 Windwalker\Router\Exception\RouteNotFoundException

try
{
    $route = $router->match('flower/25');
}
catch (RouteNotFoundException $e)
{
    Application::close('Page not found', 404);
    
    exit();
}
catch (\Exception $e)
{
    // Do other actions...
}