danielspeir/rust

Rust 是一款功能齐全的 PHP 5.4+ 路由器,支持反向路由和 RESTful API 支持。

v1.0.0 2015-07-19 16:34 UTC

This package is not auto-updated.

Last update: 2024-10-02 09:41:38 UTC


README

Rust 是一款功能齐全的 PHP 5.4+ 路由器,支持反向路由和 RESTful API 支持。

下载 Rust

composer require danielspeir/rust

示例用法

// Get router instance
$router = Rust::getRouter();

// Build 'blog' Parent Route
$router->route('blog', function(){

  $this->response(function(){
    return $this->renderView('blog');
  });
  
});

// Build 'blog/new' Child Route
$router->route('blog/new', function(){

  $this->get(function(){
    return $this->renderView('blog-add');
  });

  $this->post(function(){
    // On successful insert to database:
    return $this->redirect('blog/' . $newBlogId);
  });
  
});

// Build 'blog/:id' Dynamic Child Route
$router->route('blog/:id', function(){

  $this->response(function($id){
    return $this->renderView('blog-single', compact('id'));
  });
  
});

// Serve routes
$router->serve();

开始使用 Rust

路由作用域

'route' 方法接受至少两个参数:路由路径和路由动作。路由动作可以是一个字符串,路由器会直接打印它,或者是一个闭包对象,路由器会调用它。

基本字符串返回
  $router->route('blog', 'Show all blogs');
闭包返回
  $router->route('blog', function(){
	// Route Scope
  });

每当提供闭包对象作为路由动作时,这个闭包对象内部的所有内容都被认为是处于“路由作用域”之内。所有响应方法(get、post、delete 等)必须在路由作用域内调用。

索引路由('/')

您的应用程序的索引路由(即您的首页或根页)是通过传递单个正斜杠作为路由路径来定义的。

$router->route('/', function(){
  // Route Scope
});

或者,您也可以使用索引路由方法执行此操作,因为它只是上面代码的别名。

$router->index(function(){
  // Route Scope
});

######>> 快速跳转:这两种方法都可以在路由命名空间中使用,用于定义父路由。

响应方法作用域

响应方法的用法直接受限于路由作用域,用于根据请求方法向路由提供特定的动作。响应方法最多接受一个参数(除了我们稍后要讨论的控制台),可以是两种类型之一:一个字符串(将被打印)或一个闭包对象(将被调用)。

响应方法的完整列表如下

  • get()
  • post()
  • put()
  • patch()
  • delete()
  • response()
  • before()
  • beforeAll()
  • beforeChildren()
  • controller()

######>> 快速跳转:控制台方法与其说是响应方法,不如说是一个响应方法 操作器

示例用法
	$router->route('blog', function(){
	
	  // Return a view on Get
	  $this->get(function(){
		// This is the Response Method Scope
	    return $this->returnView('blogs');
	  });
	  
	  // Manually echo a string on Post
	  $this->post(function(){
	    // Option 1:
	    echo "Posting a blog!";

		// Option 2:
		return "Posting a blog!";
	  });

	  // Let Rust echo the string on Delete
	  $this->delete('No deleting is allowed');
	  
	});

在第一个示例中,我们使用 Rust 的 'renderView' 函数在 Get 请求中将视图文件发送到 'blog' 路由。

在第二个示例中,我们使用两种不同的方法在响应方法作用域内手动打印字符串,针对 Post 请求。第一种是简单地打印它,第二种是返回它。每个响应方法都可以,但不是必须的,返回一个值。返回 null 或 true 将始终按预期渲染路由;然而,返回 false 将渲染“否则”路由并抛出 404 响应。

第三个示例将字符串参数传递给 delete 方法,这相当于在闭包对象中手动返回字符串。

方法概述:get(), post(), put(), patch(), 和 delete()

一次只渲染 REST 方法之一(get、post、put、patch 和 delete)。Rust 通过将渲染时的服务器请求方法变量与之匹配来确定要提供哪种方法。这允许构建 RESTful 端点。

方法概述:response

在不存在其他适用请求的情况下,会渲染 'response' 方法。例如,如果您在路由作用域内只定义了一个 'response' 方法,那么 Rust 会为该路由的每个请求渲染该方法,而不管请求方法是什么。但是,如果您提供了 'get' 和 'response' 方法,Rust 就会在 Get 请求上渲染 'get' 方法,在所有剩余的请求类型(post、put、patch、delete 等)上渲染 'response' 方法。

方法概述:before()、beforeAll()、beforeChildren()

'before' 方法是渲染在所有其他请求之前的中间件函数。'beforeAll' 和 'beforeChildren' 函数仅限于在父路由作用域中使用,而 'before' 方法可以在父路由作用域和子路由作用域中同时使用。这些方法特别有用,例如,在渲染端点之前对用户访问 API 端点进行身份验证。

在父路由作用域中,'beforeAll' 会先于父路由和所有子路由渲染,而 'beforeChildren' 只会在子路由之前渲染,不会在父路由之前。

  // The Parent Route
  $router->route('blog', function(){
  
	// Renders only before this Parent Route
    $this->before('String Return');

	// Renders before Parent and Child Route(s)
	$this->beforeAll('String Return');

	// Renders only before Child Route(s)
	$this->beforeChildren('String Return');

  });

  // The Child Route
  $router->route('blog/:id', function(){
  
    // Renders only before this Child Route, 
    // but after the beforeAll and beforeChildren
    // from the Parent.
	$this->before('String Return');

  });

方法概述:controller

controller 方法是唯一可以接受最多两个参数的响应方法。第一个参数是控制器文件,第二个参数是控制器类。如果控制器类的名称与控制器文件不同,则需要第二个参数。

######>> 快进:控制器在反向路由部分有更详细的介绍。

  $router->route('blog', function(){
    $this->controller('ctrlFile', 'ctrlClass');
  });

命名空间作用域

可以使用 'group' 方法将路由家族(即路由父及其子)命名空间化,以避免重复。'group' 方法是围绕所有 'route' 方法的包装器。

在命名空间内构建路由时,您可以使用索引路由方法中的任何一个来构建父路由。

  $router->group('blog', function(){
    
    // Route: 'blog' (Option 1)
    $this->route('/', 'String Return');

	// Route: 'blog' (Option 2)
	$this->index('String Return');

	// Route: 'blog/new'
	$this->route('new', 'String Return');

    // Dynamic Route: 'blog/:id'
    $this->route(':id', 'String Return');
    
  });

######>> 快进:使用 Rust 的 'serveFromDirectory' 函数时,所有单个路由文件都会根据文件名自动命名空间。

动态路由

您只需在每个要设置为动态的路由参数前面加上一个冒号,就可以简单地构建动态路由。然后,每个动态参数将按顺序作为所有路由作用域内响应方法的参数访问。

	$router->route('blog/:id/:action', function(){
	
	  $this->response(function($id, $action){
	    return $action . ' Blog Number ' . $id;
	  });
	  
	}); 

在浏览器中导航到新路由 'blog/32/Delete' 将产生

	Delete Blog Number 32

动态参数转换

所有动态参数都以字符串形式传递给响应方法作用域,但在某些情况下,您可能希望以不同的方式转换这些参数。您可以在响应方法中手动执行此操作,或者使用 Rust 提供的两个选项之一。

选项 1:castParams 函数

castParams 函数接受一个关联数组参数。

$router->castParams([
  'id' => 'int',
  'action' => 'string'
]);

castParams 函数可以在 3 个不同级别调用:全局级别、命名空间级别或路由级别。Rust 将按特定顺序评估。路由级别是最具体的,然后是命名空间,最后是全局。

/* 
  Global Level
  Specificity Level: Least Specific.
  
  Will cast ALL ':id' Route parameters defined
  in your application as 'int', unless overwritten
  by a more specific castParams.
*/
$router->castParams(['id' => 'int']);

$router->group('blog', function(){
  /*
    Namespace Level
    Specificity Level: Moderately Specific.
    
    Will overwrite any Global Level castParams 
    and will cast all ':id' Route parameters 
    used within this Namespace as 'int'.
  */
  $this->castParams(['id' => 'int']);
  
  $this->route(':id', function(){
    /*
      Route Level
      Specificity Level: Most Specific.
    
      Will overwrite any Global and Namespace 
      Level castParams and will cast the ':id'
      Route Parameter as an 'int' only for this 
      Route.
    */
    $this->castParams(['id' => 'int']);
    $this->get(function($id){
      return gettype($id);
    });
  });
});

可以在路由过程的任何点使用 $router->cleanCastParams() 函数清除和重置参数转换。

#####选项 2:匈牙利符号转换 Rust 中还有另一种用于参数转换的选项,称为匈牙利符号转换。它使用匈牙利命名约定为特定路由转换参数类型,是 最最 具体的选项,因为它将覆盖所有 castParam 级别。

$router->route('blog/:iId', function(){
  $this->get(function($id){
    return gettype($id);
  });
});

动态特定顺序

在构建动态路由时,请注意,更具体的路由(即那些在相同位置明确声明静态参数的路由,这些参数与您的动态路由声明的动态参数相同)应先于较不具体的路由定义。例如

  // Most Specific
  $router->route('blog/new', 'Add a new blog');

  // Less Specific
  $router->route('blog/:id', 'Show blog with id.');

在这个例子中,如果较不具体的路由在较具体的路由之前声明,那么当您在浏览器中导航到 'blog/new' 时,Rust 会首先渲染较不具体的路由,并将 'new' 传递给 'id' 位置。为了避免这种情况,我们首先声明 'blog/new'。

无效路由

Rust 中的无效路由是不能声明子路由,也不能在命名空间中定义的路由。总共有三个:所有路由、其他路由和索引路由。

除了索引路由外,无效路由前面都有一个冒号,并且不能直接从浏览器访问。

所有路由

所有路由是一个中间件路由,它在您的应用程序中的每个路由请求之前渲染。

$router->all(function(){
  // Route Scope
});

'all' 函数只是一个别名

$router->route(':all', function(){
  // Route Scope
});

因此,所有路由可以像任何正常路由一样接受响应方法。':all' 路由的独特之处在于它被构建为在您的应用程序中的其他任何路由之前渲染。':all' 路由不能通过 URI 访问。

其他路由

其他路由在没有适用路由的情况下渲染,或者当响应方法明确返回 false 时。

$router->otherwise(function(){
  // Route Scope
});

像 'all' 函数一样,这只是一个别名

$router->route(':otherwise', function(){
  // Route Scope
});

像 ':all' 路由一样,':otherwise' 路由也不能通过 URI 访问。当没有定义其他路由时,Rust 会回退到“死亡消息”,这可以通过 Rust 的 'config' 方法进行配置。

######>> 快进: 使用 death_message 配置选项来自定义应用程序的回退错误消息。

索引路由

索引路由,尽管它前面没有冒号并且可以通过 URI 访问,但由于它不能接受直接子路由或在命名空间中定义,因此仍然被视为无效路由。

### Rust 存储Rust 提供了一个存储对象,可以轻松地通过路由层次结构持久化数据。这个对象可能很有用,例如,在将数据从所有路由向下传递到路由,或者使用父路由的 'before' 方法从父路由传递数据到子路由时。

// Store an item
$router->store()->userId = 32;

一旦存储了一个项,就可以将其作为参数传递给 'store' 函数以进行检索。将变量作为参数传递允许 Rust 判断它是否已设置,并将根据判断返回真值或假值。

// Retrieve an item
echo $router->store('userId');

否则,按标准检索

// Retrieve an item
echo $router->store()->userId;

可以使用 cleanStorage 函数在任何时候清理和重置存储对象。

$router->cleanStore();

实用函数

在 Rust 中,实用函数是 Rust 类的方法,只能在响应方法作用域内使用。在作用域之外使用它们在生产环境中不会有任何影响。在开发环境中,将抛出错误。

######>> 快进: 设置 Rust 的环境类型。

  • json()
  • redirect()
  • renderView()

json()

##### 可用参数

  • data | 混合类型
  • setHeader | 布尔值

Rust 使用输出缓冲区封装来自路由器的响应。json 方法会清理当前输出缓冲区,设置 'application/json' 内容类型标题(除非另有说明),并回显编码的 json 数据。

$router->route('blog/:id', function(){

  $this->get(function($id){
    $blogRecord = // fetch a blog record by $id
    return $this->json($blogRecordObject);
  });	
  
});

redirect()

##### 可用参数

  • location | 字符串
  • 响应代码 | 布尔值或整数 | 默认:false

与 json 方法类似,redirect 方法会清理输出缓冲区,然后使用 302 响应代码重置标题位置。您可以将布尔值 'true' 作为第二个参数传递以强制 301 永久重定向,或者您可以提供自定义响应代码。

$router->route('blog', function(){

  $this->get(function(){
    return $this->redirect('/');
  });
  
});

renderView()

##### 可用参数

  • path | 字符串
  • 变量 | 数组

renderView 函数允许您从响应方法直接渲染模板文件。它接受两个参数:视图路径和要暴露给该视图的变量数组(如果有的话)。

路径参数假设为.php,因此不需要指定文件类型;然而,明确定义文件类型将覆盖Rust的假设。视图的路径始终相对于路由文件。与路由文件处于同一级别的视图文件可以按如下方式渲染:

$router->route('blog', function(){
  $this->get(function(){
    return $this->renderView('blog');
    // Or, if it were an HTML file
    return $this->renderView('blog.html');
  });
});

如果视图文件位于“views”目录中,我们可以使用view_directory配置选项来声明Rust预先附加到renderView路径参数的路径,或者可以在方法内部手动声明完整路径。两种方式都可以。

######>> 快进: Rust配置。

$router->config([
  'view_directory' => 'views';
]);

$router->route('blog', function(){
  $this->get(function(){
    // renders 'views/blog.php'
    return $this->renderView('blog');
    // Or, if view_directory is not set:
    return $this->renderView('views/blog');
  });
});

为了将变量暴露给视图,必须将定义的变量数组作为关联数组传递给renderView函数的第二个参数位置。

array(
  'first_name' => 'daniel',
  'last_name' => 'speir'
);

此关联数组将导致这些变量暴露给您的视图

视图文件
<h1>
  <?php echo $first_name . ' ' . $last_name; ?>
</h1>

PHP有两个函数可以轻松生成此关联数组:get_defined_vars()compact().

$router->route('blog/:id', function(){
  $this->get(function($id){
    // Using get_defined_vars()
    return $this->renderView('blog', get_defined_vars());

    // Using compact()
    return $this->renderView('blog', compact('id'));
  });
});

在这种情况下,这两个函数生成相同的数组;然而,如果Response方法作用域中定义的变量比您希望暴露给视图的变量多,get_defined_vars()可能会产生不希望的结果。compact()通常是此任务最安全的选项。

辅助工具

辅助工具与实用工具方法一样是公共方法,但不受任何作用域限制。辅助工具可以在路由构建的任何位置或任何作用域中使用。

  • isAjax()
  • liveRoute()
  • liveRouteParent()
  • isRoute()
  • isRouteParent()
  • isParent()
  • getQueryString()
  • setRequestMethod()
  • getRequestMethod()
  • isGet()
  • isPost()
  • isPut()
  • isPatch()
  • isDelete()

isAjax()

#####无参数。

如果端点是通过Ajax请求的,则返回true。注意:此函数使用了HTTP_X_REQUESTED_WITH服务器变量,一些服务器可能无法提供此变量。在依赖此方法之前,请确保您的服务器使用此变量。

if ($router->isAjax()) { 
  // render json data
}

liveRoute()

#####无参数。返回Rust渲染的路线名称。例如,'blog/:id'或'blog/new'。

$this->liveRoute();

liveRouteParent()

#####无参数。返回Rust渲染的父路线名称。例如,'blog'。

$this->liveRouteParent();

isRoute()

##### 可用参数

  • 路线名称 | 字符串

如果提供的路线名称参数与liveRoute()匹配,则返回true。

if ($this->isRoute('blog/:id')){
  // do something
}

isRouteParent()

##### 可用参数

  • 父路线名称 | 字符串

如果提供的父路线名称参数与liveRouteParent()匹配,则返回true。

if ($this->isRouteParent('blog')){
  // do something
}

isParent()

无参数。

如果liveRoute()liveParentRoute()相同,则返回true。换句话说,实时路线是父路线。

if ($this->isParent()){
  // do something
}

getQueryString()

##### 可用参数

  • 查询字符串索引 | 字符串或布尔值 | 默认:false

如果没有参数,则返回查询字符串参数作为关联数组。如果有参数,则返回提供的查询字符串变量的值。

// Return full array
$router->getQueryString();

// Return one value
$router->getQueryString('myVar');

setRequestMethod()

##### 可用参数

  • 请求方法 | 字符串

设置服务器请求方法变量的值。不区分大小写。

$router->setRequestMethod('post');

getRequestMethod()

无参数。

返回服务器请求方法变量的值。

$router->getRequestMethod();

isGet(), isPost(), isPut(), isPatch(), isDelete()

无参数。

这些参数中的每一个都会在服务器的请求方法变量与相应的方法名称匹配时返回true。

if ($this->isDelete()){
  // do something
}

配置

Rust的config()方法接受一个特定的键/值对的关联数组,允许您根据应用程序的需求配置Rust。

$router->config([
  'dev' => true,
  'controller_directory' => 'controllers',
  'view_directory' => 'views',
  'death_message' => 'Page not found!'
]);

所有配置选项

  • all_route_file
  • build_all
  • controller_directory
  • controller_rust_object
  • death_message
  • dev
  • index_route_file
  • method_setter
  • otherwise_route_file
  • render_all_before_otherwise
  • set_request_method
  • unit_test
  • view_directory

all_route_file, otherwise_route_file, index_route_file

接受:字符串

默认:all_route_file = '_all.php'

默认:otherwise_route_file = '_otherwise.php'

默认:index_route_file = '_index.php'

配置选项 all_route_fileotherwise_route_fileindex_route_file 允许您定义 Rust 的 serveFromDirectory() 方法在构建所有、否则和索引路由时使用的特定文件名。默认值如下:

######>> 快进:使用 Rust 的 serveFromDirectory() 方法。

build_all

接受:布尔值

默认:false

Rust 路由类遵循一个简单的原则:仅构建所需内容。每当您的应用程序请求一条路由时,Rust 就会构建它认为必要的路由(这些称为相关路由),然后为您提供服务。也就是说,如果您构建了 'blog' 路由和 'about_me' 路由,Rust 在任何时候只需要了解其中之一:通过 URI 请求的路由。同样,如果您使用 GET 方法请求 'blog' 路由,Rust 不需要了解该路由中构建的 POST 或 PUT 方法,因为它们不会被渲染或服务。通过采用这种方法,Rust 能够通过仅构建和提供它认为相关的路由来保持快速和高效。

话虽如此,Rust 中的 build_all 配置选项会覆盖这个原则。通过将此选项设置为 true,Rust 将构建应用程序中定义的所有路由,无论它们是否相关。

注意不建议在生产应用程序中使用此选项,因为它会给服务器带来不必要的负担。仅在开发环境中使用 build_all

controller_directory

接受:字符串

默认:无

controller_directory 选项允许您指定控制器将从其中加载的目录。提供给此选项的值将被添加到应用程序路由中声明的所有控制器之前。

$router->config([
  'controller_directory' => 'controllers';
]);

$router->route('blog', function(){
  $this->get(function(){
	// Requires 'controllers/myCtrl.php'
    $this->controller('myCtrl');
  });
});

####controller_rust_object

接受:布尔值、字符串

默认:'rust'

当在应用程序中使用 Rust 控制器方法和反向路由时,有时需要在控制器类中检索 Rust 对象的实例。通过将 Rust 对象暴露给控制器,您能够访问所有 Rust 工具和帮助方法,并通过控制器在 Rust 的 store 对象中持久化数据。

默认情况下,Rust 使用 'rust' 变量来实现这一点。

class blogController {

  public function index(){
    return $this->rust->json($data);
  };

}

controller_rust_object 选项允许您配置该变量的名称,或者选择不设置它。'false' 值将告诉 Rust 不要在控制器中设置该对象。

####death_message

接受:字符串

默认:'请求的路由无法渲染'。

如果由于任何原因无法渲染路由,Rust 首先会查找一个替代的 Otherwise 路由进行渲染。如果找不到 Otherwise 路由,它将回退并打印 death_message 值。

####dev

接受:布尔值

默认:false

Rust 被构建成一个优雅的路由系统,因此 Rust 总是会寻找在出现错误时优雅退出的方法。例如,如果您在 Response 方法之外使用了一个工具函数,Rust 将简单地忽略该声明并继续构建或渲染而不会出现中断。然而,在某些情况下,您可能希望 Rust 在方法未按预期使用时抛出警告。将 dev 选项设置为 true 将允许这样做。

####method_setter

接受:字符串

默认:':method'

由于HTML表单元素只能接受GET或POST的'method'属性值,我们必须通过另一种请求方法(如put、patch或delete)欺骗表单进行提交。method_setter选项允许您定义在提交表单时确定应设置何种请求方法并随后渲染的表单输入名称。

<form method="POST">
  <input type="hidden" name=":method" value="PATCH" />
</form>

####render_all_before_otherwise

接受:布尔值

默认:false

Rust的全路由是一个中间件路由,它在应用中的其他任何路由之前渲染。这一规则有一个例外,即默认情况下,全路由不会在否则路由之前渲染。render_all_before_otherwise选项允许您修改这种行为,如果您的应用需要的话。

####set_request_method

接受:布尔值

默认值:true

此选项允许您定义是否希望利用Rust通过method_setter选项提供的功能。如果设置为false,则method_setter选项将无效。

####unit_test

接受:布尔值

默认:false

unit_test选项仅在单元测试Rust时使用。此选项允许Rust模拟浏览器通常会提供的一些行为,并在dev模式下优雅死亡后禁止Rust停止构建或渲染。

将此选项用于其目的之外将产生不希望的结果。

####view_directory

接受:字符串

默认:无

view_directory选项允许您指定视图将被加载的目录。提供给此选项的值将添加到应用程序路由中声明的所有视图中。

$router->config([
  'view_directory' => 'views';
]);

$router->route('blog', function(){
  $this->get(function(){
	  // Requires 'views/blog.php'
	  return $this->renderView('blog');
  });
});

反向路由

基础知识

Rust通过controller()响应方法提供了一个非常基本的方式来处理反向路由。在路由作用域中使用控制器方法会改变所有后续响应方法的渲染方式。例如,在下面的场景中,当请求并渲染路由时,字符串参数会被打印到浏览器。

$router->route('blog', function(){
  $this->get('Get Blogs');
});

然而,当我们在一个路由作用域中定义一个控制器时,我们是在告诉Rust将路由控制权交给我们所定义的控制器。在下面的场景中,字符串参数将不再打印到浏览器,而是会指向一个应该在该请求方法上渲染的控制器类方法。

路由文件
$router->route('blog/:id', function(){

  $this->controller('blogController');
  
  /*
    String will now refer to a controller method, 
    and any arguments will be automatically passed
    to that method.
  */
  $this->get('index');

  // A Closure argument will not be affected by this
  $this->post(function(){
    // Will render normally
  });
  
});
控制器文件
class blogController {

  public function index($id){
    // renders on Get request to 'blog' route
  }

}

controller()方法

如前所述,控制器方法是唯一可以接受最多两个参数的响应方法。第一个参数,控制器文件,是必需的。第二个参数,控制器类名,仅在控制器文件名和类名不匹配时才是必需的。

Rust假定第一个参数的文件扩展名为.php,因此不需要预先添加它。提供扩展名将覆盖Rust的假设。

#####blogController.php

class blog {

	// innards

}

在这种情况下,需要第二个控制器参数,因为文件名和类名不匹配。

$router->route('blog', function(){
  $this->controller('blogController', 'blog');
});

注意:控制器文件的路径和.php扩展名不会影响此行为。例如

$router->route('blog', function(){
  $this->controller('app/controllers/blogController.php');
});

Rust仍然会提取'blogController'并假定它是类名,如果没有提供第二个参数。

######>> 回顾:使用controller_directory配置选项设置预定义的控制器路径。

在控制器中使用Rust

有时需要在控制器类中检索Rust对象的实例。通过将Rust对象暴露给控制器,您可以访问所有Rust实用程序和辅助方法,以及通过控制器在Rust的store对象中持久化数据。

默认情况下,Rust 使用 'rust' 变量来实现这一点。

class blogController {

  public function index(){
    return $this->rust->json($data);
  };

}

######>> 回顾:使用controller_rust_object配置选项更改此变量名称。

服务路由

构建完所有路由后,需要通知Rust何时开始提供服务。您可以在路由声明末尾使用serve()方法来完成此操作。Rust仅会评估在实例检索Rust::getRouter()和serve之间构建的路由。

$router = Rust::getRouter();

// Build your routes

$router->serve();

如果您打算使用Rust的serveFromDirectory()方法来服务单个路由文件,那么在它后面不需要提供serve()方法,因为这是隐含的。

单个路由文件(serveFromDirectory)

基础知识

对于小型应用程序,在单个文件中定义所有路由是一种简单且高效的方式来控制应用程序中的路由;然而,对于大型应用程序,这可能会很快变得非常混乱。使用Rust的serveFromDirectory()函数可以帮助您将应用程序的路由整理成小块,便于理解和处理。

// Get router instance
$router = Rust::getRouter();

// Define any configuration
$router->config([
  'view_directory' => 'views'
]);

// Serve from the 'routes' directory.
$router->serveFromDirectory('routes');

自动命名空间

每当在应用程序中请求路由时,Rust都会查找'routes'目录以找到所需的文件,并构建其内容。因此,您的路由文件名称必须与在命名空间中定义的名称相同。

所有路由文件都必须在命名空间作用域内。

routes/blog.php
// Route: 'blog' (Option 1)
$this->route('/', 'String Return');

// Route: 'blog' (Option 2)
$this->index('String Return');

// Route: 'blog/new'
$this->route('new', 'String Return');

// Dynamic Route: 'blog/:id'
$this->route(':id', 'String Return');

上面的示例与在命名空间中声明路由参数完全相同。唯一的区别是Rust自动命名空间了所有路由文件。这意味着在路由文件中,$this上下文立即可用,无需额外操作即可获取。

纯净的路由文件

正如您所知,在Rust中有3个纯净路由。也就是说,这些路由不能有子路由,也不能在命名空间内定义。这3个路由分别是:索引路由('/')、所有路由和否则路由。由于这种限制,使用Rust的serveFromDirectory方法时,这3个路由不会被自动命名空间。此外,由于这些路由的性质,它们使用预定义的文件名,以便Rust在请求时知道需要加载和渲染哪些内容。

所有纯净路由文件都必须在路由作用域内。

索引路由文件:'_index.php' 所有路由文件:'_all.php' 否则路由文件:'_otherwise.php'

######>> 回顾:这些预定义的文件名可以通过index_route_fileall_route_fileotherwise_route_file配置选项进行自定义。

与纯净路由自动命名空间不同,它们被“自动路由”。

#####routes/_index.php

$this->get('Return this string to the Index Route.');

上面的示例与不使用serveFromDirectory方法的执行完全相同

$router->route('/', function(){
  $this->get('Return this string to the Index Route.');
});

与正常路由文件一样,纯净路由中的$this上下文立即可用,无需任何额外操作。