路由是框架处理传入请求的主要任务。 在这里,定义负责请求地址的路由,并分配后续的操作。
有时在框架中,路由也被称为“路由”,两者是同一个概念。
项目的路由由开发者在文件 /routes/map.php 中定义,来自 "routes" 文件夹的其他路由文件可以包含在此文件中,组合起来形成路由映射。 这些路由的一个显著特点是,在加载时,框架会检查其整体的正确性以及所使用方法的顺序。如果出现异常,会生成带有异常原因的错误。 由于路由映射中的所有路由都经过验证,这保证了它们的整体正确性。
在首次请求之后或使用特定的控制台命令时,路由会更新并缓存。 因此,路由文件不应包含外部代码,只应包含 Route 类的方法。
如果在修改路由映射后,框架没有生成相应的提示信息,那么在将来的操作中这些信息不会再出现,至少在下一次修改相关路由文件之前不会出现。
路由由 Route 类的方法定义,其中最常用的一个方法是 get()。 此类方法仅用于路由映射中。
此方法允许您在指定条件下处理 HTTP GET 方法。 如示例所示:
该路由将在访问网站根 URL 时显示 "Hello, world!" 这行文字。 要从模板中渲染 HTML 代码(可能包含 PHP 代码),该方法与 view() 函数一起使用。
HLEB2 框架根据应用程序开发人员定义的方案处理任意地址,例如:
在这种情况下,所有符合条件方案 "site.com/resource/.../.../" 的 URL 地址将返回相同的文本字符串,并且 "version" 和 "page" 的值可以通过 Hleb\Static\Request 对象访问:Request::param("version")->asString() 和 Request::param("page")->asPositiveInt()。
这些值也可以通过容器和控制器方法中的同名参数获得。
在路由地址中,可以指定最后一部分可能是可选的:
如果地址缺失,它仍与该路由匹配,但'id' 的值将为 NULL。
示例动态路由,其中为 second 和 third 命名部分指定了默认值。
类似于 '/example/{first}/two/three?',但在给定的 Request 中,会将附加值 'second' => 'two', 'third' => 'three' 添加到已存在的动态参数 'first'。如果最终参数缺失,则将为 null。
多重路由分配(在 Request::param() 中将会出现一个编号数组,包含 URL 的部分):
框架不允许将 URL 的部分解释为复合段,因为这与标准相悖,但对此规则有一个例外。
一个常见的情况是用户登录名在 URL 中用特殊的 @ 标签作为前缀。
可以如下设置:
该函数指定从 /resources/views/ 文件夹中与路由关联的模板。 /resources/views/index.php 文件的示例:
可以将变量作为第二个参数传递给函数,使用命名数组。
变量将在模板中可用。
对于预定义地址 '404','403' 和 '401',view() 函数中将显示相应的标准错误页面。
有时候,为了在路由中指定某些预先定义的文本响应,需要设置适当的 Content-Type 标头并输出一些请求参数。目前,仅支持注入原始路由地址、地址中的动态参数以及 HTTP 请求方法。例如:
在路由中使用 redirect() 方法来指定地址重定向。它可以包含指向内部或外部 URL 的链接,还可以包括从原始路由获取的动态查询参数:
路由分组用于通过向组中添加方法为路由分配通用属性,方法的行为将应用于整个组。
组的作用范围通过在组的开头使用方法 toGroup() 来定义,并在结束时使用 endGroup() 结束。
在这种情况下,添加到组中的方法 prefix() 将应用于组内的所有路由。
组可以嵌套到其他组中。此外,还存在组的另一种语法:
每个路由都可以分配一个唯一的名称。
该名称可用于生成其 URL,使代码与实际的 URL 地址解耦。
通过使用路由名称而不是地址来实现这一点。
例如,此网站通过使用路由名称生成页面链接。
类似于 get() 方法处理 HTTP 的 GET 方法,存在与 POST, PUT, PATCH, DELETE, OPTIONS 相对应的 post(), put(), patch(), delete(), options() 方法。
这些方法与它们各自的 HTTP 方法相匹配,除了 options()。
在其他所有情况下,OPTIONS 方法是按照标准处理的,但在 options() 中,您可以单独定义如何处理 OPTIONS 请求(重新定义它们)。
分配给路由时,它匹配所有 HTTP 方法,在其他方面类似于 get()。
类似于 get() 方法,但具有一个额外的第一个参数,您可以在其中传递一个支持的 HTTP 方法数组。
捕获所有未匹配的路径,适用于所有 HTTP 方法(或指定的)。对于特定的 HTTP 方法在路由中只能有一个 fallback() 方法。
这样可以为未找到匹配(而不是 404 错误)的所有类型 HTTP 方法或单独指定处理方法。
用于防御 CSRF 攻击的方法是 protect(). 将其分配给路由或路由组将添加对之前设置的特殊令牌的检查。
工作原理如下:
在页面上输出访问令牌,可以使用 csrf_token() 或 csrf_field() 函数。
通过 JavaScript 或表单与请求一起发送此令牌。
请求的路由具有 protect() 方法并检查令牌。
控制器 是 MVC 架构的一部分(用于 web 的 Action-Domain-Responder),负责对路由器识别的请求进行后续处理,但不应包含业务逻辑。
控制器无法用于路由组,它是针对某个具体或单独路由分配的。 为此使用方法 controller()。
在示例中,第一个参数是分配的控制器类,第二个参数是使用的控制器方法。
'index' 方法可以省略,因为它是默认使用的。
注意,使用控制器时 get() 方法不再需要第二个参数。
如果一个控制器只能被分配给一个路由,那么可以应用多个中间件 (middlewares)。您也可以将 中间件 分配给一组路由。
middleware() 方法意味着中间件会在主路由处理程序之前执行。 该方法有类似的 before() 方法和 after() 方法(在主处理程序之后运行)。 这里的主处理程序是指路由返回的文本、分配的模板或控制器的执行。
指定的中间件按声明的顺序执行。
中间件方法的参数与控制器类似。第二个参数可以指定要执行的方法,默认是 'index'。 不同之处在于第三个参数可以传递一个数组参数给 middleware。 这些参数可以通过 Hleb\Static\Router::data() 方法或通过容器获取。
模块是一种控制器。它指向项目的 /modules/ 目录,并包含所使用的 模块 名称。
路由的 URL 中可以包含动态部分,可以使用 where() 方法为这些部分定义规则。
在此示例中,名为 'lang'、'user' 和 'id' 的部分将通过正则表达式进行验证。
特殊方法 domain() 可以分配给一个路由或一组路由。
第一个参数可以指定域名或子域名,第二个参数定义规则匹配的级别。
有一种方法可以根据动态 URL 的值来确定目标控制器和方法。
在这种情况下,路由可能如下所示:
在这个例子中,对于 URL /page/part/first/,框架将尝试将控制器确定为 'MainPartController' 和方法为 'initFirst'(按照camelCase原则转换)。
在处理程序中使用替换原则应谨慎管理,因为 URL 数据可能导致调用未预见的控制器或方法。
此外,您可以通过使用键 '[verb]' 来指定对请求 HTTP 方法 的依赖。
在此示例中,对于 URL /page/example/,框架将尝试确定控制器为 'MainExampleGetController' 和方法为 'getMethod'(按照camelCase原则转换)。
对于 POST 方法,这些将是 'MainExamplePostController' 和 'postMethod'。
替换的功能在根据控制器方法分配请求 HTTP 方法时特别有用。
默认情况下,在 /routes/map.php 文件进行更改后,框架会自动更新路由缓存。 还有一个命令行更新路由缓存的命令:
$php console --routes-upd
对于高流量项目,您可能需要禁用 production 中的自动更新,并仅通过控制台命令重新计算路由缓存。
这可以通过在 /config/common.php 文件中配置 'routes.auto-update' 设置来实现。