在现代Web框架(Laravel,Symfony,Silex,仅举几例)中,似乎有一种使用routes.php
文件或类似方法将URI附加到控制器的模式。通过选择使用PHP注释,Laravel可以更轻松。
但对我来说,这一切都感觉像是一些代码重复,当你创建/修改控制器逻辑时,你必须始终保持路由文件。有趣的是,我在几个旧框架中看到了一种更简单的方法,我曾经在我的旧项目中使用它:
控制器。 src/controllers
文件夹中的所有类(旧方式)或YourApp\Controllers
命名空间中的所有类都通过添加“控制器”自动映射到URL的第一部分“对它。示例:/auth
映射到AuthController
,/product/...
- ProductController
和/
- 默认为IndexController
。
操作。操作是网址的第二部分,它会映射到方法名称。因此,/auth/login
会调用AuthController::loginAction()
方法。如果没有提供第二部分,我们会尝试indexAction()
。不希望人们访问某些内部方法?不要公之于众。
参数。 URL的下一部分正在映射到方法的参数;如果参数列表中有Application
和/或Request
类型提示,则会跳过它们以便正确注入它们;我们可以像往常一样通过Request访问GET / POST变量。
以下是完整示例,将所有这些功能结合在一起使用:
URL: https://example.com/shop/category/computers?country=US&sort=brand
namespace MyApp\Controllers;
class ShopController extends BaseController {
public function categoryAction(Application $app, Request $req, $category, $subcategory = null) {
echo $category; // computers
echo $subcategory; // null, it's optional here
echo $req->get('country'); // US
echo $req->get('sort'); // brand
}
}
我确信它最初似乎缺乏一些熟悉的功能,但是如果需要,可以轻松添加我能想到的所有功能 - 使用可连接的提供程序,连接中间件,分支控制器到子控制器,指定HTTP方法,甚至对参数执行一些预验证。它非常灵活。
这种方法确实可以加快路由的创建和管理。所以除了在一个文件中包含所有路由之外(考虑到各种提供程序,在Silex中使用 - > mount()或在Symfony中使用捆绑包),除了这些路由之外,现代框架似乎更喜欢这种做MVC的方式通过我描述的更简单的方式路由?我错过了什么?
答案 0 :(得分:2)
同样请注意,Symfony的标准版附带了SensioFrameworkExtraBundle,它允许使用注释而不是基于文件的声明:
/**
* @Route("/")
*/
public function indexAction()
{
// ...
}
以同样的方式,您可以设置整个控制器文件的前缀:
/**
* @Route("/blog")
*/
class PostController extends Controller
{
/**
* @Route("/{id}")
*/
public function showAction($id)
{
}
}
但是,我们必须声明它。我认为主要原因是路由需求受到SEO优化的严重影响。对于任何面向公众的内容,您需要一些富含关键字的网址。 "公众"逻辑组织可能也不同,你可能只有一个控制器来传递你所有的静态页面,你仍然想要那些/联系,/关于......
在某些域中,可以使用约定推断路由。如果使用FosRestBundle创建REST API,它将根据资源方法中的控制器/操作名称自动生成路由。总的来说,我认为FosRestBundle在他们的方法中有很多东西,你可以同时轻松地解析和验证查询参数:
class FooController extends Controller
{
/**
* This action route will be /foo/articles, GET method only
*
* @QueryParam(name="val", default="75 %%")
*/
public function getArticlesAction(ParamFetcher $paramFetcher)
{
...
}
答案 1 :(得分:2)
我将从Symfony / Silex的角度讲这里:
routes.php
提供了URL映射和控制器的分离。您需要添加或更改URL吗?你直接去routes.php
。如果你想改变很多它们,非常方便。routes.php
是一种更灵活的方法。搜索引擎优化可能会变得疯狂,可能需要你有像/shop_{shopName}/{categoryName}/someStaticKeyword/{anotherVar}
这样的路线。使用routes.php
,您可以轻松地将其映射到您的代码,但如果您的路由直接映射到代码,这可能会成为一个问题。更重要的是,你可以拥有这个唯一的控制器,你不需要为每个斜杠部分编写控制器。您甚至可以让不同的控制器使用不同的可变部分处理相同的URL,例如/blog/[\d]+
或/blog/[a-z-]+
由不同的控制器处理(一个可能生成重定向到另一个控制器)。你可能永远不需要做这样的事情,但这只是这种方法灵活性的证明 - 一切皆有可能。routes.php
通过->assert
方法提供简单的验证方法。也就是说,routes.php
不仅会将网址映射到控制器方法,还会确保这些网址符合特定要求,而且您不必在代码中执行此操作(在大多数情况下,这会花费更多时间)代码写)。此外,您可以为某些变量创建默认断言,例如,您可以确保{page}
或{userId}
始终为\d+
,routes.php
中的单行将负责{page}
或{userId}
。routes.php
的另一个功能是网址生成。您可以为任何路由分配任何名称(通过->bind()
方法),然后根据该名称生成URL,并为更改的URL部分提供变量。一旦我们在整个代码中使用此系统并使用网址生成器,我们就可以根据需要更改网址,但除了routes.php
之外,我们无需编辑任何内容。再一次 - 这些是灵活的名称,一旦URL发生变化,您不必在整个项目中随处更改,并且您不必选择名称。它可能比URL短得多,或者更冗长。/blog/[\d+]
到/blog/[a-z-]+
。此外,您可能希望保留这两个网址一段时间,并使旧的重定向到新的)。使用routes.php
,您只需添加一个新行并添加待办事项备忘录,以便在以后删除时将其删除。当然,所有这一切都可以通过任何方式实现。但是,这种方法会如此简单,灵活,透明和紧凑吗?
答案 2 :(得分:0)
原因可能是长期可维护性。路线的建立方式并不重要,但一般来说,Laravel作为一个框架,侧重于简化和使框架变得更好的小事。只要它易于用户(在这种情况下是Web开发人员),就可以实现目标。
如果您的应用程序中有很多路径,您可以为routes.php文件使用不同的名称,也可以使用多个路由文件。
您可以尝试重新思考整个概念以改进它,但我不认为Laravel的路线需要真正的重大改变才能让它变得更加容易。它已经很简单了。也许它将来会有所改善,但就目前而言,我认为这很好。
答案 3 :(得分:0)
我总是喜欢在配置文件中使用路由而不是使用注释,因为首先,我觉得它更易于维护,更容易进行疏忽。当您可以一起看到它们时,更容易确保您没有任何冲突的路线。
此外,它在理论上更快。注释需要反射,应用程序需要扫描文件系统并解析每个控制器以收集路由集。