Ser*_*rov 5 php model-view-controller routing symfony laravel
在现代 Web 框架(Laravel、Symfony、Silex 等)中,似乎有一种使用routes.php文件或类似方式将 URI 附加到控制器的模式。Laravel 通过使用 PHP 注释的选项使其变得更容易。
但对我来说,这一切都像是代码重复,当您创建/修改控制器逻辑时,您必须始终将路由文件放在手边。有趣的是,我在几个旧框架中看到了一种更简单的方法,我曾经在我的旧项目中也使用过它:
控制器。src/controllers文件夹中的所有类(旧方式)或YourApp\Controllers命名空间中的所有类都通过向 URL 添加“控制器”自动映射到 URL 的第一部分。示例:/auth被映射到AuthController、/product/...— 到ProductController和/— 到 default IndexController。
行动。Action 是 URL 的第二部分,它被映射到方法名称。所以,/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
}
}
Run Code Online (Sandbox Code Playgroud)
我确定一开始它似乎缺少一些熟悉的功能,但是如果需要,我能想到的所有功能都可以轻松添加 - 使用可附加的提供程序,连接中间件,将控制器分支到子控制器,指定 HTTP 方法,甚至执行一点对参数的预验证。它非常灵活。
这种方法将真正加快路由创建和管理。因此,除了在一个文件中包含所有路由(考虑到各种提供者,在 Silex 中使用 ->mount() 或在 Symfony 中使用 bundles,这也并非总是如此),现代框架似乎更喜欢这种进行 MVC 路由的方式的原因是什么?通过我描述的更简单的方式?我错过了什么?
我将从 Symfony/Silex 的角度在这里发言:
routes.php提供 URL 映射和控制器的分离。您需要添加或更改网址吗?你直接去routes.php。如果你想改变很多,非常方便。routes.php是一种更灵活的方法。SEO 可能会变得疯狂,并且可能需要您拥有像/shop_{shopName}/{categoryName}/someStaticKeyword/{anotherVar}. 随着routes.php您可以轻松地这个映射到您的代码,但如果您的路由直接映射到代码,这可能成为一个问题。更重要的是,您可以拥有这个唯一的控制器,您不需要为每个斜杠部分编写控制器。您甚至可以让不同的控制器处理具有不同变量部分的相同 URL,例如/blog/[\d]+或/blog/[a-z-]+由不同的控制器处理(一个可能会生成重定向到另一个)。您可能永远不需要做这样的事情,但这只是这种方法灵活性的证明 - 有了它,一切皆有可能。routes.php通过->assert方法提供简单的验证方法。也就是说,routes.php不仅将 URL 映射到控制器方法,还要确保这些 URL 符合特定要求,并且您不必在代码中执行此操作(在大多数情况下,这需要编写更多代码)。此外,您可以为某些变量创建默认断言,例如,您可以确保{page}或{userId}始终是\d+,其中的单行routes.php将处理{page}或的所有用法{userId}。routes.php是 url 生成。您可以为任何路由分配任何名称(通过->bind()方法),然后根据该名称生成 URL,并为更改的 URL 部分提供变量。一旦我们有了这个系统并在我们的代码中使用了 URL 生成器,我们就可以随意更改 URL,但除了routes.php. 再一次 - 这些是灵活的名称,一旦 URL 更改,您就不必在整个项目中随处更改,并且您不受选择名称的限制。它可能比 URL 短得多,或者更冗长。/blog/[\d+]to /blog/[a-z-]+。此外,您可能希望将它们都保留一段时间,并使旧的重定向到新的)。随着routes.php您只需添加一个新行,并添加一个待办事项备忘录,以在一段时间内将其删除,如果你想在以后将其删除。当然,所有这些都可以通过任何方法实现。但这会像这种方法一样简单、灵活、透明和紧凑吗?