Skip to content

路由基础#

在 PHP 应用程序(如 XF2)中,我们需要一种方法能够处理用户对特定 URL 的请求,理解该 URL 对应的控制器、操作和数据,以便向用户呈现适当的响应。将 URL 转换为代码中的位置这一概念被称为"路由"。

在 XF2 中,路由几乎完全通过管理后台的一个位置进行管理。该位置是 管理后台 > 开发 > 路由。路由分为两种类型:公共类型和管理类型,它们分别提供公共应用和管理应用内的请求路由。

简单示例#

在路由页面(见上文)中,您应该能看到列出的 account/ 条目。这是一个公共路由,为访问 URL index.php?account/ 的请求提供路由。这个特定路由非常简单,仅包含少量配置。值得注意的是,它由"路由前缀"、部分上下文和控制器类组成。让我们更详细地理解这些部分:

路由前缀#

路由前缀本质上是 index.php? 之后、第一个 / 之前的部分。它是确定将请求路由到哪个控制器的第一步。

部分上下文#

部分上下文告诉 XF 内的导航系统,当访问者查看通过此路由导向的页面时,应选择哪个导航项。对于公共路由,部分上下文应是顶级导航条目的 ID。对于管理路由,这应指向最具体的后台导航条目 ID(无论层级如何)。

在账户路由的情况下,默认情况下部分上下文并不适用,因为我们没有"账户"导航标签。但为了观察其效果,只需将"部分上下文"值更改为"forums",保存更改并转到前台的账户页面。您现在应该看到"Forums"导航标签被选中!

控制器#

这是当请求匹配此路由时应调用的控制器类名。在"account/"路由的情况下,我们指定了 XF:Account。这将加载 Account 控制器。(有关更多信息,请参见短类名)。该代码位于以下位置 src/XF/Pub/Controller/Account.php。注意短类名如何解析为"中缀"(Pub)以及前缀(XF)和后缀(Account)。在这种情况下,该控制器的中缀(Pub)是从账户路由类型(公共)推断出来的。

控制器操作#

上文我们解释了如何将路由匹配到特定控制器,但我们还不知道如何调用该控制器中的特定操作。控制器本质上是包含多个操作方法的类,而 URL 中路由前缀之后的部分表示控制器操作。给定 URL index.php?account/account-details,您应被路由到类 XF\Pub\Controller\Account 和名为 actionAccountDetails() 的方法。如果路由未指定操作,则调用的方法只是 actionIndex()

您可以在控制器基础部分阅读更多关于控制器的信息。

进阶示例(路由格式)#

让我们看看 members/ 路由。这个路由仍然很简单,就像 account/ 路由一样,但它多了一个填充字段:"路由格式"。要了解其工作原理,请查看前台您的用户资料。该资料的 URL 将类似于 index.php?members/your-name.1。特别注意 your-name.1 部分。这是我们试图使用"路由格式"匹配的部分。

"路由格式"允许我们从请求 URL 中提取数据,以便将该信息传递到控制器操作中,使操作能加载特定信息;在本例中,它加载请求的用户资料详细信息。它还可以帮助我们根据传入的数据构建链接。以下是语法:

路由格式
:int<user_id,username>/:page

值得注意的是,个人资料 URL 中用于查找资料的重要部分实际上不是 your-name 部分,而是用户 ID(1)。为了演示这一点,请更改 URL 并将 your-name 替换为 not-your-name。您将看到正确的资料被找到,并执行重定向到正确的 URL。

上述格式表示这是一个基于整数的参数。对于构建出站链接,我们从传入数据的 user_id 键中提取整数。如果 username 键被传入数据中,它将被"slug 化"并附加到整数 ID 前,就像您在资料 URL 中看到的那样。对于匹配传入的 URL,这会转换为匹配整数参数格式的正则表达式。

:page 是生成链接中 page-123 部分的快捷方式。在本例中,它在链接参数中查找 page。如果找到,则放入 URL 并从参数中删除。对于传入解析,如果匹配(可以为空),则会将页码添加到传递给控制器的参数中。

路由参数#

当路由匹配到特定控制器和操作时,URL 中的任何参数都会被包装到一个我们称为 ParameterBag 的特殊对象中。该对象专门设计用于将普通 URL 参数与来自路由匹配的参数分开。ParameterBag 对象被传递到每个控制器操作中,使用方式如下:

PHP
$userId = $params->user_id;

子名称#

还可以将路由进一步拆分为子名称。通过查看 members/following 路由可以看到这一点。在此示例中,followingmembers 路由的子名称。通常,类似 index.php?members/following 的 URL 中,following 部分将指示操作,并简单地与普通 members/ 路由匹配。但是,如果有匹配前缀"members"和后续"子名称"的路由,则将使用该路由。这里就是这种情况,因此它会构建如下链接:

路由格式
members/:int<user_id,username>/following/:page

对于传入的路由匹配,此路由将在基本 members 路由之前被测试;如果匹配,则会被使用。

这种子名称系统允许行为变更,例如更改参数位置或将路由子分组到不同控制器或使用不同参数。您可以在资源管理器和媒体库附加组件中看到后者的示例。