文档/路由

路由

路由是框架处理传入请求的主要任务。 在这里,定义负责请求地址的路由,并分配后续的操作。

有时在框架中,路由也被称为“路由”,两者是同一个概念。

项目的路由由开发者在文件 /routes/map.php 中定义,来自 "routes" 文件夹的其他路由文件可以包含在此文件中,组合起来形成路由映射。 这些路由的一个显著特点是,在加载时,框架会检查其整体的正确性以及所使用方法的顺序。如果出现异常,会生成带有异常原因的错误。 由于路由映射中的所有路由都经过验证,这保证了它们的整体正确性。

在首次请求之后或使用特定的控制台命令时,路由会更新并缓存。 因此,路由文件不应包含外部代码,只应包含 Route 类的方法。

如果在修改路由映射后,框架没有生成相应的提示信息,那么在将来的操作中这些信息不会再出现,至少在下一次修改相关路由文件之前不会出现。

路由由 Route 类的方法定义,其中最常用的一个方法是 get()。 此类方法仅用于路由映射中。


#Route::get() 方法

此方法允许您在指定条件下处理 HTTP GET 方法。 如示例所示:

Route::get('/''Hello, world!');

该路由将在访问网站根 URL 时显示 "Hello, world!" 这行文字。 要从模板中渲染 HTML 代码(可能包含 PHP 代码),该方法与 view() 函数一起使用。


#动态地址

HLEB2 框架根据应用程序开发人员定义的方案处理任意地址,例如:

Route::get('/resource/{version}/{page}/''Dynamic address used');

在这种情况下,所有符合条件方案 "site.com/resource/.../.../"URL 地址将返回相同的文本字符串,并且 "version""page" 的值可以通过 Hleb\Static\Request 对象访问:Request::param("version")->asString()Request::param("page")->asPositiveInt()
这些值也可以通过容器和控制器方法中的同名参数获得。

在路由地址中,可以指定最后一部分可能是可选的:

Route::get('/profile/user/{id?}/''Variable ID value');

Route::get('/contacts/form?/''Optional end part');

如果地址缺失,它仍与该路由匹配,但'id' 的值将为 NULL。


#动态地址的默认值

示例动态路由,其中为 secondthird 命名部分指定了默认值。

Route::get('/example/{first}/{second:two}/{third:three?}''defaults value in dynamic route');

类似于 '/example/{first}/two/three?',但在给定的 Request 中,会将附加值 'second' => 'two', 'third' => 'three' 添加到已存在的动态参数 'first'。如果最终参数缺失,则将为 null


#可变地址

多重路由分配(在 Request::param() 中将会出现一个编号数组,包含 URL 的部分):

Route::get('/example/...0-5/''From 0 to 5 arbitrary parts');
// or
Route::get('/example/...1-3,7,9,11-20/''Number of parts within the specified range');

#地址中的标签

框架不允许将 URL 的部分解释为复合段,因为这与标准相悖,但对此规则有一个例外。
一个常见的情况是用户登录名在 URL 中用特殊的 @ 标签作为前缀。 可以如下设置:

Route::get('/profile/@{username}''Username with tag');

#view() 函数

该函数指定从 /resources/views/ 文件夹中与路由关联的模板。 /resources/views/index.php 文件的示例:

Route::get('/'view('index'));

可以将变量作为第二个参数传递给函数,使用命名数组。

Route::get('/'view('index', ['title' => 'Index page']));

变量将在模板中可用。

<?php
// File /resources/views/index.php

/** @var string $title */
echo $title// Index page

对于预定义地址 '404','403' 和 '401',view() 函数中将显示相应的标准错误页面。


#预览功能 preview()

有时候,为了在路由中指定某些预先定义的文本响应,需要设置适当的 Content-Type 标头并输出一些请求参数。目前,仅支持注入原始路由地址、地址中的动态参数以及 HTTP 请求方法。例如:

Route::any('/page/{name}'preview('Current route {{route}}, request parameter {%name%}, request method {{method}}'));

#函数 redirect()

在路由中使用 redirect() 方法来指定地址重定向。它可以包含指向内部或外部 URL 的链接,还可以包括从原始路由获取的动态查询参数:

Route::get('/old/address/{name}')->redirect('/new/address/{%name%}'301);

#路由分组

路由分组用于通过向组中添加方法为路由分配通用属性,方法的行为将应用于整个组。
组的作用范围通过在组的开头使用方法 toGroup() 来定义,并在结束时使用 endGroup() 结束。

Route::toGroup()->prefix('example');

    
// /example/first/page/
    
Route::get('first/page''First page content');
    
// /example/second/page/
    
Route::get('second/page''Second page content');

Route::endGroup();

在这种情况下,添加到组中的方法 prefix() 将应用于组内的所有路由。

组可以嵌套到其他组中。此外,还存在组的另一种语法:

Route::toGroup()
    ->
prefix('example')
    ->
group(function () {
        
// /example/first/page/
        
Route::get('first/page''First page content');
        
// /example/second/page/
        
Route::get('second/page''Second page content');
    });

#命名路由

每个路由都可以分配一个唯一的名称。

Route::get('/'view('default'))->name('homepage');

该名称可用于生成其 URL,使代码与实际的 URL 地址解耦。
通过使用路由名称而不是地址来实现这一点。 例如,此网站通过使用路由名称生成页面链接。


#处理 HTTP 方法

类似于 get() 方法处理 HTTPGET 方法,存在与 POST, PUT, PATCH, DELETE, OPTIONS 相对应的 post(), put(), patch(), delete(), options() 方法。

这些方法与它们各自的 HTTP 方法相匹配,除了 options()
在其他所有情况下,OPTIONS 方法是按照标准处理的,但在 options() 中,您可以单独定义如何处理 OPTIONS 请求(重新定义它们)。

Route::options('/ajax/query/''...')->controller(OptionsController::class);

Route::post('/ajax/query/''{"result": "ok"}')->name('post.example.query');

#Route::any() 方法

分配给路由时,它匹配所有 HTTP 方法,在其他方面类似于 get()


#Route::match() 方法

类似于 get() 方法,但具有一个额外的第一个参数,您可以在其中传递一个支持的 HTTP 方法数组。

Route::match(['get''post'], '/''Handler for POST and GET methods');

#Route::fallback() 方法

捕获所有未匹配的路径,适用于所有 HTTP 方法(或指定的)。对于特定的 HTTP 方法在路由中只能有一个 fallback() 方法。

这样可以为未找到匹配(而不是 404 错误)的所有类型 HTTP 方法或单独指定处理方法。


#路由保护

用于防御 CSRF 攻击的方法是 protect(). 将其分配给路由或路由组将添加对之前设置的特殊令牌的检查。

Route::get'/ajax/query''Protected route')->protect();

工作原理如下:
在页面上输出访问令牌,可以使用 csrf_token()csrf_field() 函数。
通过 JavaScript 或表单与请求一起发送此令牌。
请求的路由具有 protect() 方法并检查令牌。


#控制器分配

控制器MVC 架构的一部分(用于 web 的 Action-Domain-Responder),负责对路由器识别的请求进行后续处理,但不应包含业务逻辑。

控制器无法用于路由组,它是针对某个具体或单独路由分配的。 为此使用方法 controller()

use App\Controllers\DefaultController;

Route::get('/')->controller(DefaultController::class, 'index');

在示例中,第一个参数是分配的控制器类,第二个参数是使用的控制器方法。 'index' 方法可以省略,因为它是默认使用的。
注意,使用控制器时 get() 方法不再需要第二个参数。


#中间件控制器

如果一个控制器只能被分配给一个路由,那么可以应用多个中间件 (middlewares)。您也可以将 中间件 分配给一组路由。

Route::toGroup()
    ->
middleware(FirstGeneralMiddleware::class)
    ->
middleware(SecondGeneralMiddleware::class);

    
Route::get('/example''...')->middleware(GetMiddleware::class);
    
Route::post('/example''...')->middleware(PostMiddleware::class);

Route::endGroup();

middleware() 方法意味着中间件会在主路由处理程序之前执行。 该方法有类似的 before() 方法和 after() 方法(在主处理程序之后运行)。 这里的主处理程序是指路由返回的文本、分配的模板或控制器的执行。

指定的中间件按声明的顺序执行。

中间件方法的参数与控制器类似。第二个参数可以指定要执行的方法,默认是 'index'。 不同之处在于第三个参数可以传递一个数组参数给 middleware。 这些参数可以通过 Hleb\Static\Router::data() 方法或通过容器获取。


#模块

模块是一种控制器。它指向项目的 /modules/ 目录,并包含所使用的 模块 名称。

Route::get('/section/')->module('default'DefaultModuleController::class);

#Where() 方法验证

路由的 URL 中可以包含动态部分,可以使用 where() 方法为这些部分定义规则。

Route::toGroup()
    ->
prefix('/{lang}/')
    ->
where(['lang' => '[a-z]{2}']);

    
Route::post('/profile/{user}/{id}''...')
        ->
where(['user' => '/[a-z]+/i''id' => '[0-9]+']);

Route::endGroup();

在此示例中,名为 'lang''user''id' 的部分将通过正则表达式进行验证。


#域限制

特殊方法 domain() 可以分配给一个路由或一组路由。
第一个参数可以指定域名或子域名,第二个参数定义规则匹配的级别。


#替换原则

有一种方法可以根据动态 URL 的值来确定目标控制器和方法。
在这种情况下,路由可能如下所示:

Route::get('/page/{controller}/{method}')
    ->
controller('Main<controller>Controller''init<method>');

在这个例子中,对于 URL /page/part/first/,框架将尝试将控制器确定为 'MainPartController' 和方法为 'initFirst'(按照camelCase原则转换)。

在处理程序中使用替换原则应谨慎管理,因为 URL 数据可能导致调用未预见的控制器或方法。

此外,您可以通过使用键 '[verb]' 来指定对请求 HTTP 方法 的依赖。

Route::match(['get''post'], '/page/{target}')
    ->
controller('Main<target>[verb]Controller''[verb]Method>');

在此示例中,对于 URL /page/example/,框架将尝试确定控制器为 'MainExampleGetController' 和方法为 'getMethod'(按照camelCase原则转换)。
对于 POST 方法,这些将是 'MainExamplePostController''postMethod'

替换的功能在根据控制器方法分配请求 HTTP 方法时特别有用。


#更新路由缓存

默认情况下,在 /routes/map.php 文件进行更改后,框架会自动更新路由缓存。 还有一个命令行更新路由缓存的命令:

$php console --routes-upd

对于高流量项目,您可能需要禁用 production 中的自动更新,并仅通过控制台命令重新计算路由缓存。
这可以通过在 /config/common.php 文件中配置 'routes.auto-update' 设置来实现。

使用托管 控制器

页面翻译:chatgpt 4-o
返回顶部