蛋白质/路由

简单快捷的URL路由器

1.1.0 2019-05-29 15:17 UTC

This package is auto-updated.

Last update: 2024-08-29 05:06:51 UTC


README

蛋白质 | 路由

简单快捷的URL路由器

安装

composer require proteins/route

通过

use Proteins\Route;

URL映射

您可以通过on方法定义路由。

Route::on('/hello',function(){
   echo 'Hello, Friend!';
});

这是定义响应于URL /helloHTTP GET路由的最简单形式。
您可以使用流畅的API接口将相同的路由映射到多个请求方法。

Route::on('/hello')
  ->via('get','post')
  ->with(function(){
     echo 'Hello, Friend!';
  });

via方法接受一个字符串数组,用于处理HTTP请求方法。

with方法将可调用的函数绑定到路由。

如果您需要将不同的HTTP方法映射到单个URL的不同回调(例如通过REST API公开资源),则map方法允许您传递一个method => callback字典。

Route::map('/entity(/:id)/?',[
    'get' => function($id=null){
		// READ: fetch the $id element or all if $id === null
    },
    'post' => function($id=null){
    	// CREATE: build a new element
    },
    'put' => function($id=null){
    	// UPDATE: modify $id element's properties
    },
    'delete' => function($id=null){
    	// DELETE: delete $id element
    },
])

any简写会触发响应于URL /hello 的任何HTTP动词的路由。

Route::any('/hello',function(){
   echo 'Hello, World!';
});

这等同于做

Route::on('/hello')
  ->via('*')
  ->with(function(){
     echo 'Hello, World!';
  });

URL模式匹配和参数提取

路由模式本质上是一个正则表达式,有一些细微的差别。

模式将始终与REQUEST_URI参数的end部分匹配(已移除查询字符串)。

规则

  • 每个(...)组都是可选的
  • 您可以通过:named_parameter提取参数
  • 模式不能包含#字符

示例

Route::on('/element(/:id)/?',function($id=null){
	if (null === $id){
		$result = get_all_elements();
	} else {
		$result = get_element_by_id($id);
	}
	print_r($result);
});

在这个示例中,可选的(在(...)组中):id在存在时被提取,并且路由可以可选地通过/结束。

此路由处理以下所有请求

  • /element
  • /element/
  • /element/123
  • /element/123/
  • /element/1919191
  • /element/462635
  • 等等。

但是,如您所见,此示例还处理了/element/fooo。如果我们想给提取的参数提供格式规则,我们可以使用rules方法。

rules方法接受一个named_parameter => regex字典。

rules([ 'parameter_name' => 'parameter_regex_pattern' ])

我们可以在前面的示例中为接受仅整数值(由正则表达式模式\d+定义)的id参数添加规则。

示例

Route::on('/element(/:id)/?',function($id=null){
	if (null === $id){
		$result = get_all_elements();
	} else {
		$result = get_element_by_id($id);
	}
	print_r($result);
})
->rules([ 'id' => '\d+' ]);

路由分组

您可以根据前缀模式封装路由。如果当前请求不匹配组URL模式,则不会注册相对路由定义。

注意:此行为受core.route.pruning标志控制。

此功能可用于响应时间优化和将路由树挂载到动态URL前缀。

您可以定义多个嵌套路由组

示例

管理部分

Route::group('/admin',function(){

    Route::on('/',function(){
        echo "Admin Index";
    });

    Route::on('/login')
    ->via('get','post')
    ->with(function(){
        // Handle login
    });

    Route::on('/logout',function(){
       // handle logout
    });

    Route::group('/dashboard',function(){

      Route::on('/',function(){
         // Dashboard
      });

      Route::on('/details',function(){
         // Dashboard Details
      });

    });

});

带有动态参数的路由组

路由组可以有动态参数,这些参数将与正常路由一样被提取。

Route::group("/book/:id", function($id){
  $book = new Book($id);
 
  Route::on("/", function() use ($book){
    return $book;
  });

  Route::on("/:field", function($field) use ($book){
    return $book->$field;
  });

});

路由中间件

您可以在路由或路由组之前和之后附加中间件列表。

如果中间件返回false,则整个路由执行将停止。

中间件可以链接,before将按照反向声明顺序(FIFO)执行,after将按照直接声明顺序(LIFO)执行。

Route::on('/',
	"[TEST]"
)
->before(function(){
    echo "(B1)";
})
->before(function(){
    echo "(B2)";
})
->after(function(){
    echo "(A1)";
})
->after(function(){
    echo "(A2)";
});

输出如下

(B2)(B1)[TEST](A1)(A2)

您可以使用路由组一次性将中间件应用于多个路由

Route::group('/private',function(){
    
    Route::on('/', ... );
    Route::on('/dashboard', ... );
    Route::on('/profile', ... );
    Route::on('/settings', ... );

})->before(function(){
    if ( ! user_authorized() ) {
        Response::error(403,"Forbidden");
        return false;
    }
});

分发路由

请记住在脚本结束之前调用dispatch方法以执行路由。

Route::on('/hello',function(){
   echo 'Hello, Friend!';
});

// Run the route dispatcher.
Route::dispatch();

您可以重写请求URI和方法,通过将它们作为参数传递给dispatch方法。

Route::dispatch($URL=null, $method=null, $return_route=false)

示例

Route::dispatch('/my/forced/uri','OPTIONS');

如果匹配到(如果有)的路由,可以通过将true传递给return_route参数,而无需自动执行返回的路由。

$matched_route = Route::dispatch(null,null,true);

路由找不到匹配项。(HTTP 404)

当没有路由与当前请求匹配时,将触发404事件。

您可以将视图追加到Response中,以显示一个礼貌页面。

Event::on(404,function(){
  Response::html( View::from('errors/404') );
});

渲染快捷方式

除了渲染回调之外,您还可以传递一个字符串或视图,以进行直接渲染。

闭包

Route::on('/',function(){
  return View::from('index');
});
<h1>I'm the index!</h1>

一个View

Route::on('/', View::from('index') );
<h1>I'm the index!</h1>

一个字符串(不是一个可调用的字符串)

Route::on('/', 'Not a callable string' );
Not a callable string

一个对象

Route::on('/',(object)[
  'alpha' => 123,
  'beta'  => [1,2,3]
]);
{"alpha":123,"beta":[1,2,3]}

HTTP/2资源推送

您可以直接从路由和路由组定义中推送资源。
语法与Response::push方法相同方法

Route::on('/', function() {
  return View::from('index');
})->push([
  'style'  => '/assets/css/main.css',
  'script' => [
    '/assets/js/vendors.js',
    '/assets/js/main.js',
  ],
]);

URL标记和反向路由

您可以通过tag方法给路由添加一个名称标签。

Route::on('/user/:id', function ($id) {
  return "USER[$id]";
})->tag('user');

通过Route::tagged($name)方法检索命名路由。

$user_route = Route::tagged('user');

要获取路由的URL,请使用getURL($params = [])方法。

echo $user_route->getURL();

作为快捷方式,您还可以通过Route::URL($name, $params = [])助手获取命名路由的URL。

echo Route::URL('user');
/user

您还可以传递一个数组来映射和分配路由的动态值。

echo Route::URL('user',[
  'id' => 123,
]);
/user/123

注意: Route::URL方法的返回值是一个[[URL]]对象。

事件和过滤器

路由具有Events特质的行为,唯一的不同之处在于,Events::on方法被重命名为onEvent,以避免与Route::on处理器冲突。

Route::onEvent('start',function($route, $args, $method){
   echo "Called route.\n";
});

可用事件

可用过滤器