c9s / roller
高性能PHP路由器
Requires
- php: >=5.3.0
- corneltek/serializerkit: ~1
- doctrine/common: ~2.3
Requires (Dev)
- corneltek/phpunit-testmore: dev-master
This package is not auto-updated.
Last update: 2024-09-14 12:51:54 UTC
README
PHP Roller 是一个简单快速的PHP路由器。
Roller 将您的路由编译成一个简单的数组来存储路由,因此它很快。
除此之外,Roller 提供了一个扩展来提高您的性能。
特性
- 高度可定制
- 灵活
- 简单的 DSL(类似 Sinatra 语法)
- 支持 APC 缓存。
- 支持文件缓存。
- 内置的 RESTful 路由生成器,资源处理器。
- 可定制的 RESTful 路由生成器,资源处理器。
- 简单、有用的路由路径语法。 (类似 Rails 风格)
- 高性能(通过 PHP 扩展,比纯 PHP 版本快 1607%)
- 高单元测试覆盖率,覆盖率 > 88%。
- 适用于框架。
- 支持注解读取器。
基准测试
ROUTE CONSOLE DUMPER
安装
使用 Composer 安装
{ "require": { "corneltek/roller": "~1.8" } }
通过 PEAR 安装
pear channel-discover pear.corneltek.com
pear install corneltek/Roller
或克隆此仓库
pear install -f package.xml
将此库作为 git 子模块使用:克隆此仓库,选择一个 PSR-0 类加载器,并将 src/
添加到类路径。
要使用控制台转储器,您需要 ezc/ConsoleTools,请使用 PEAR 安装程序进行安装
pear channel-discover components.ez.no
pear install -a ezc/ConsoleTools
概述
Roller 路由器为您提供了一个简单的 DSL 来声明类似 Sinatra 的路由
require 'bootstrap.php'; require 'Roller/DSL.php'; on('/path/to/:date',function() { return 'your content'; }); on('/path/to/:year', [ ':year' => '\d+' ] ,function() { return 'your content'; }); dispatch( $_SERVER['PATH_INFO'] );
更多用法
初始化一个路由器
$router = new Roller\Router;
添加一个使用简单回调的新路由
$router->add( '/blog/:id/:title' , function($id,$title) { return 'Blog'; });
添加一个使用类回调的新路由
$router->add( '/blog/:year/:month/:id/:title' , array('Controller','method') );
添加一个使用类/操作回调字符串的新路由
$router->add( '/path/to/blog' , 'Controller:methodName' );
添加一个有要求的新路由
$router->add( '/path/to/:year' , array('Callback','method') , array( ':year' => '\d+', ));
添加一个有要求和闭包的新路由
$router->add( '/path/to/:year' , function($year) { return $year; },array( ':year' => '\d+', ));
或通过 any
$router->any( '/path/to/:year' , function($year) { return $year; }, array( ':year' => '\d+', ));
GET 方法的别名
$router->get( '/path/to/:year' , function($year) { ... } );
POST 方法的别名
$router->post( '/path/to/:year' , function($year) { ... } );
元属性
Roller 当前支持: method
、default
、requirement
、post
、get
属性。
添加一个有要求和默认值的新路由
$router->add( '/path/to/:year' , array('Callback','method') , array( ':year' => '\d+', 'default' => array( 'year' => 2000, ), ));
添加一个有请求方法(如 POST 方法)的新路由
$router->add( '/path/to/:year' , array('Callback','method') , array( ':year' => '\d+', 'method' => 'post', 'default' => array( 'year' => 2000, ), ));
RouteSet
RouteSet 是一个路由集合类,您可以将路由集合挂载到另一个路由集合。
使用 RouteSet 非常简单
$subroutes = new Roller\RouteSet; $subroutes->add( '/subitem' , $cb ); $routes = new Roller\RouteSet; $routes->mount( '/item' , $subroutes );
挂载路径
挂载路由集合
$routes = new Roller\RouteSet; $routes->add( '/path/to/:year' , array( 'Callback', 'method' ) ); $routes = new Roller\RouteSet; $routes->mount( '/root' , $routes ); $router = new Roller\Router( $routes );
分发
分发路径
$r = $router->dispatch( $_SERVER['PATH_INFO'] );
评估响应内容
if( $r !== false ) echo $r(); else die('page not found.');
自定义路由类
class YourRoute extends Roller\MatchedRoute { // customze here. } $r = new Roller\Router(array( 'route_class' => 'YourRoute' )); $route = $r->dispatch( '/path/to/...' ); // get YourRoute object.
为控制器使用注解读取器
class AnnotationTestController { /** * @Route("/hello/:name", name="_hello", requirements={":name" = ".+"}, vars={ "k" = 123, "b" = 234 }) */ function helloAction($name) { return $name; } /** * @Route("/") */ function indexAction() { return 'index'; } } $router = new Roller\Router; $router->importAnnotationMethods( 'AnnotationTestController' , '/Action$/' ); $route = $router->dispatch('/'); $route(); // returns 'index' $route = $router->dispatch('/hello/John'); $route(); // returns "John"
缓存
启用 apc 缓存
$router = new Roller\Router( null , array( 'cache_id' => '_router_testing_' ));
启用文件缓存
$router = new Roller\Router( null , array( 'cache_id' => '_router_testing_', 'cache_dir' => 'tests/cache', ));
RESTful 接口
Roller Router 有一个内置的 RESTful 路由生成器,定义一系列 RESTful 路由非常简单,Roller Router 还提供了一个简单的 RESTful 路由生成器,自定义自己的 RESTful 路由也很简单。
首先,初始化一个 RESTful 插件对象
$router = new Roller\Router; $restful = new Roller\Plugin\RESTful(array( 'prefix' => '/restful' ));
将 RESTful 插件添加到您的路由器管理器
$router->addPlugin($restful);
支持 RESTful 的两种解决方案
ResourceHandler
:如果您需要为每个资源定义不同的逻辑,您可以使用ResourceHandler
,您可以将不同的资源逻辑分离到不同的处理器类中。GenericHandler
:如果您的资源使用相同的逻辑和相同的权限控制,您可以为每个资源使用GenericHandler
。
使用 ResourceHandler,将您的资源 ID 注册到路由器中,与您的资源处理器类名相关联,每个资源 ID 都映射到一个资源处理器
$restful->registerResource( 'blog' , 'BlogResourceHandler' );
定义您的资源处理器,以下是一个简单的博客示例,它定义了 RESTful CRUD 的工作方式
use Roller\Plugin\RESTful\ResourceHandler; class BlogResourceHandler extends ResourceHandler { public function create() { $this->codeCreated(); return array( 'id' => 1 ); } public function update($id) { $put = $this->parseInput(); return array( 'id' => 1 ); } // delete a record. public function delete($id) { return array( 'id' => 1 ); } // load one record public function load($id) { return array( 'id' => $id , 'title' => 'title' ); } // find records public function find() { return array( array( 'id' => 0 ), array( 'id' => 1 ), array( 'id' => 2 ), ); } }
关于状态码,请参见下面的列表
- codeOk (200)
- codeCreated (201)
- codeAccepted (202)
- codeNoContent (204)
- codeBadRequest (400)
- codeForbidden (403)
- codeNotFound (404)
在您分发URL之前,路由对象会调用ResourceHandler
类的expand
方法,该方法将RESTful路由生成到路由对象的路由集中。下面是生成的URL
GET /restful/blog - get blog list
GET /restful/blog/:id - get one blog record
POST /restful/blog - create one blog record
PUT /restful/blog/:id - update one blog record
DELETE /restful/blog/:id - delete one blog record
您可以重写expand
方法来定义自己的RESTful URL风格。
现在您应该能够分发RESTful URL了
$_SERVER['REQUEST_METHOD'] = 'get'; $r = $router->dispatch('/restful/blog/1'); // returns {"success":true,"data":{"id":"1","title":"title"},"message":"Record 1 loaded."} $r(); $_SRVER['REQUEST_METHOD'] = 'get'; $r = $router->dispatch('/restful/blog'); // {"success":true,"data":[{"id":0},{"id":1},{"id":2}],"message":"Record find success."} $r();
自定义资源处理器
下面是RESTful路由生成器的工作方式
static function expand($routes, $h, $r) { $routes->add( "/$r(\.:format)" , array($h,'handleFind'), array( 'get' => true , 'default' => array( 'format' => 'json' ) )); $routes->add( '/' . $r . '(\.:format)' , array($h,'handleCreate'), array( 'post' => true, 'default' => array( 'format' => 'json' ) )); $routes->add( '/' . $r . '/:id(\.:format)' , array($h,'handleLoad'), array( 'get' => true, 'default' => array( 'format' => 'json' ) )); $routes->add( '/' . $r . '/:id(\.:format)' , array($h,'handleUpdate'), array( 'put' => true, 'default' => array( 'format' => 'json' ) )); $routes->add( '/' . $r . '/:id(\.:format)' , array($h,'handleDelete'), array( 'delete' => true, 'default' => array( 'format' => 'json' ) )); }
要定义自己的RESTful资源处理器(生成器),您只需从Roller\Plugin\RESTful\ResourceHandler
类继承即可
use Roller\Plugin\RESTful\ResourceHandler; class YourResourceHandler extends ResourceHandler { // define your own expand method static function expand( $routes , $handlerClass, $resourceId ) { } }
Apache的<.htaccess>文件
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ your_router.php/$1 [NC,L]
安装扩展
$ cd extension
$ phpize
$ ./configure
$ make && make install
将配置添加到您的php.ini中
extension=roller.so
破解
运行Composer安装
composer install --dev
安装ConsoleTools
pear channel-discover components.ez.no
pear install -a ezc/ConsoleTools
获取Onion并安装它
$ curl -s http://install.onionphp.org/ | bash
运行onion来安装依赖项
$ onion install
现在您应该能够运行phpunit了=)
$ phpunit tests
待办事项
- 可扩展控制器(内部的路由表)
- 自动可扩展控制器(根据方法名自动扩展路由)