在现代框架中使用routes文件的原因是什么?

时间:2016-07-04 05:08:25

标签: php laravel symfony model-view-controller routing

在现代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的方式通过我描述的更简单的方式路由?我错过了什么?

4 个答案:

答案 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的角度讲这里:

  1. 解耦。 routes.php提供了URL映射和控制器的分离。您需要添加或更改URL吗?你直接去routes.php。如果你想改变很多它们,非常方便。
  2. 灵活性。通常,routes.php是一种更灵活的方法。搜索引擎优化可能会变得疯狂,可能需要你有像/shop_{shopName}/{categoryName}/someStaticKeyword/{anotherVar}这样的路线。使用routes.php,您可以轻松地将其映射到您的代码,但如果您的路由直接映射到代码,这可能会成为一个问题。更重要的是,你可以拥有这个唯一的控制器,你不需要为每个斜杠部分编写控制器。您甚至可以让不同的控制器使用不同的可变部分处理相同的URL,例如/blog/[\d]+/blog/[a-z-]+由不同的控制器处理(一个可能生成重定向到另一个控制器)。你可能永远不需要做这样的事情,但这只是这种方法灵活性的证明 - 一切皆有可能。
  3. 验证。要考虑的另一件事是routes.php通过->assert方法提供简单的验证方法。也就是说,routes.php不仅会将网址映射到控制器方法,还会确保这些网址符合特定要求,而且您不必在代码中执行此操作(在大多数情况下,这会花费更多时间)代码写)。此外,您可以为某些变量创建默认断言,例如,您可以确保{page}{userId}始终为\d+routes.php中的单行将负责{page}{userId}
  4. 的所有用法
  5. 网址生成。 routes.php的另一个功能是网址生成。您可以为任何路由分配任何名称(通过->bind()方法),然后根据该名称生成URL,并为更改的URL部分提供变量。一旦我们在整个代码中使用此系统并使用网址生成器,我们就可以根据需要更改网址,但除了routes.php之外,我们无需编辑任何内容。再一次 - 这些是灵活的名称,一旦URL发生变化,您不必在整个项目中随处更改,并且您不必选择名称。它可能比URL短得多,或者更冗长。
  6. 可维护性。说,您可能想要更改一些网址(如上例所示 - 从/blog/[\d+]/blog/[a-z-]+。此外,您可能希望保留这两个网址一段时间,并使旧的重定向到新的)。使用routes.php,您只需添加一个新行并添加待办事项备忘录,以便在以后删除时将其删除。
  7. 当然,所有这一切都可以通过任何方式实现。但是,这种方法会如此简单,灵活,透明和紧凑吗?

答案 2 :(得分:0)

原因可能是长期可维护性。路线的建立方式并不重要,但一般来说,Laravel作为一个框架,侧重于简化和使框架变得更好的小事。只要它易于用户(在这种情况下是Web开发人员),就可以实现目标。

如果您的应用程序中有很多路径,您可以为routes.php文件使用不同的名称,也可以使用多个路由文件。

您可以尝试重新思考整个概念以改进它,但我不认为Laravel的路线需要真正的重大改变才能让它变得更加容易。它已经很简单了。也许它将来会有所改善,但就目前而言,我认为这很好。

答案 3 :(得分:0)

我总是喜欢在配置文件中使用路由而不是使用注释,因为首先,我觉得它更易于维护,更容易进行疏忽。当您可以一起看到它们时,更容易确保您没有任何冲突的路线。

此外,它在理论上更快。注释需要反射,应用程序需要扫描文件系统并解析每个控制器以收集路由集。