romeoz/rock-route

PHP 简单路由器

0.11.0 2015-11-13 07:09 UTC

This package is not auto-updated.

Last update: 2024-09-24 04:20:36 UTC


README

Latest Stable Version Total Downloads Build Status HHVM Status Coverage Status License

功能

  • 过滤器
  • 支持 REST
  • 分组
  • 向动作注入参数
  • 缓存规则
  • Rock 框架 提供独立模块/组件

目录

安装

从命令行

composer require romeoz/rock-route

或在你的 composer.json 中

{
    "require": {
        "romeoz/rock-route": "*"
    }
}

快速开始

// url: http://site.com/items/7/        

$route = new Route();
 
$handler = function(Route $route){
    return 'id: ' . $route->getParam('id');
};
       
$route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
$route->post('/items/', ['\namespace\SomeController', 'actionCreate']);
$route->run();

// output: 'id: 7'

echo Alias::getAlias('@item', ['id' => 15]); 

// output: '/items/15/'

模式

你可以使用字符串或数组作为模式。

$pattern = [
    Route::FILTER_HOST => '{sub:[a-z]+}.site.com',
    Route::FILTER_PATH => '/items/{id:\d+}/',
    Route::FILTER_GET => [
        'query' => true, 
        'view' => 'all', 
        'order' => 'sort-{order:(asc|desc)}'
    ]
]
$route->post($pattern, $handler);

'query' => true 表示 URL 参数 query 是必须的。

字符串模式 /items/{id:\d+}/ 等同于 [ Route::FILTER_PATH => '/items/{id:\d+}/' ]

可配置

你可以设置可配置的规则。在框架内部使用可能很有用。

$config = [
    'rules' => [
        'item' => [Route::GET, '/items/{id:\d+}/', $handler]
    ]
]

$route = new Route($config);
$route->run();

关于 分组

$config = [
    'groups' => [
        'api' => [
            [Route::GET, Route::POST],
            [ Route::FILTER_HOST => 'api.site.com' ],
            'rules' => [
                'item' => [Route::GET, '/items/{id:\d+}/', $handler]
            ]
        ]
    ]
]

$route = new Route($config);
$route->run();

过滤器

要使用过滤器,您必须安装 Rock Filterscomposer require romeoz/rock-filters

一个不允许通过 IP 的示例(使用 $_SERVER['REMOTE_ADDR']

$route = new Route();
 
$handler = function(){
    return 'Hello world!';
};

$filters = [
    'access' => [
        'class' => '\rock\route\filters\AccessFilter',
        'rules' => [
            'allow' => true,
            'ips' => ['10.1.2.3']
        ]
    ]
]
       
$route->get('/items/{id:\d+}/', $handler, ['filters' => $filters]);
$route->run();

####自定义过滤器(作为可调用函数)

$filters = function(Route $route){
    return $route->request->isAjax();
};

必须返回 true/false(布尔值)。

REST

$route = new Route();
      
$route->REST('items', 'ItemsController');
$route->run();

class ItemsController
{
    // GET /items/
    public function actionIndex()
    {
        return 'index';
    }

    // GET /items/7/
    public function actionShow()
    {
        return 'show';
    }

    // POST /items/
    public function actionCreate()
    {
        return 'create';
    }

    // PUT /items/7/
    public function actionUpdate()
    {
        return 'update';
    }

    // DELETE /items/7/
    public function actionDelete()
    {
        return 'delete';
    }
}

你可以指定要使用哪些动作(onlyexclude

$route->REST('items', 'ItemsController', ['only' => ['show', 'create']]);

你也可以指定自定义 REST 场景

$config = [
    'RESTHandlers' => [
            'all' => [
                Route::GET,
                '/{url}/',
                ['{controller}', 'actionAll']
            ],
            'one' => [
                Route::GET,
                '/{url}/{id}/',
                ['{controller}', 'actionOne']
            ],
            'create' => [
                [Route::POST, Route::OPTIONS],
                '/{url}/',
                ['{controller}', 'actionCreate']  
            ],
            'update' => [
                [Route::PUT, Route::PATCH, Route::OPTIONS],
                '/{url}/{id}/',
                ['{controller}', 'actionUpdate']
            ],
            'delete' => [
                [Route::DELETE, Route::OPTIONS],
                '/{url}/{id}/',
                ['{controller}', 'actionDelete'] 
            ]    
    ]
];

$route = new Route($config);

使用分组

####路由前缀

// url: http://site.com/api/items/7/  

$route = new Route();

$handler = function(Route $route) {
    $handler = function(Route $route){      
        return 'id: ' . $route['id'];
    };
    $route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
    return $route;
};

$route->group(Route::ANY, '/api/{url:.+}', $handler, ['path' => '/api/', 'as' => 'api']);
$route->run();

// output: 'id: 7'

echo Alias::getAlias('@api.item', ['id' => 15]); 

// output: '/api/items/15/'        

在这里,'path' => '/api/' 是此组规则的前缀。

####子域名路由

// url: http://api.site.com/items/7/  

$route = new Route();

$handler = function(Route $route) {
    $handler = function(Route $route){      
        return 'id: ' . $route['id'];
    };
    $route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
    return $route;
};

$route->group(Route::ANY, [ Route::FILTER_HOST => 'api.site.com' ], $handler, ['as' => 'api']);
$route->run();

// output: 'id: 7'

echo Alias::getAlias('@api.item', ['id' => 15]); 

// output: 'api.site.com/items/15/'        

路由别名

使用我们路由数组中的 as 索引,你可以将别名分配给一个路由

$route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);

echo Alias::getAlias('@item', ['id' => 15]); 

// output: '/items/15/'

扩展示例

$pattern = [
    Route::FILTER_HOST => '{sub:[a-z]+}.site.com',
    Route::FILTER_PATH => '/items/{id:\d+}/',
    Route::FILTER_GET => [
        'query' => true, 
        'view' => 'all', 
        'order' => 'sort-{order:(asc|desc)}'
    ]
]
$route->get($pattern, $handler, ['as' => 'item']);

echo Alias::getAlias('@item');

// output: {sub}.site.com/items/{id}/?view=all&order=sort-{order}

你还可以将别名设置为 分组

$route->group(
    Route::ANY, 
    [ Route::FILTER_HOST => 'api.site.com' ], 
    $handler, ['as' => 'api']
);

属于此组的所有规则都将继承此别名。

对于可配置方法,您可以使用索引

$config = [
    'rules' => [
        'item' => [Route::GET, '/items/{id:\d+}/', $handler]
    ]
]

$route = new Route($config);

echo Alias::getAlias('@item'); 

// output: '/items/{id}/'

使用响应

要使用响应,您必须安装 Rock Responsecomposer require romeoz/rock-response

$response = new \rock\response\Response;
$route = new Route(['response' => $response]);

$handler = function(Route $route){
    $route->response->format = \rock\response\Response::FORMAT_JSON;
    return ['id' => $route->getParam('id')];
};

$route->get('/items/{id:\d+}/', $handler, ['as' => 'item']);
$route->run();
$response->send();

// output: {"id":7}

更多详情 见文档

注入参数

$route = new Route;

$route->get('/', ['ItemsController', 'actionIndex'])
$route->run();

class ItemsController
{
    public function actionIndex(\rock\request\Request $request)
    {
        return $request::className();
    }
}

// output: 'rock\request\Request'

使用库 Rock DI 可以实现更灵活的使用: composer require romeoz/rock-di

HMVC(分层模型-视图-控制器)

要使用,您必须安装 Rock Responsecomposer require romeoz/rock-response

####本地

// url: http://site.com/news/7/        

$route = new Route();
 
$handler = function(Route $route){
    return 'hello';
};
       
$route->get('/foo/{id:\d+}/', $handler);
$route->post('/bar/{id:\d+}', ['\namespace\BarController', 'actionIndex']);
$route->run();

class BarController
{
    public function actionIndex(\rock\route\Route $route)
    {        
        $response = (new \rock\route\providers\Local(['route' => $route]))->send('http://site.com/foo/11/');
        return $response->getContent() . ' world!';
    }
}

// output: 'hello world!'

####远程

要使用,您必须安装 Guzzlecomposer require guzzlehttp/guzzle:6.1.*

需要 PHP 5.5+

$response = (new \rock\route\providers\Remote())->send('http://site.com/foo/11/');

缓存规则

要缓存规则/组,您必须安装 Rock Cachecomposer require romeoz/rock-cache

$cache = new \rock\cache\Memcached;

$route = new Route([
    'cache' => $cache,
    'enableCache' => true
]);

使用 flushCache() 重置缓存

$route->flushCache();

要求

  • PHP 5.4+
  • 要使用响应,需要 Rock Responsecomposer require romeoz/rock-response
  • 要使用过滤器,需要 Rock Filterscomposer require romeoz/rock-filters
  • 要使用速率限制器过滤器,需要Rock Sessioncomposer require romeoz/rock-session
  • 要使用缓存规则,需要Rock Cachecomposer require romeoz/rock-cache
  • 要使用HMVC远程调用,需要Guzzlecomposer require guzzlehttp/guzzle:6.1.*

所有非粗体依赖项为可选。

许可证

路由器是开源软件,受MIT许可证许可。