为什么MVC网站需要一个单一的入口点?


Why should MVC for websites require a single point of entry?

我看到许多网站的MVC实现都有一个单入口点,如index.php文件,然后解析URL以确定运行哪个控制器。这对我来说似乎相当奇怪,因为它涉及到必须使用Apache重写重写URL,并且有足够的页面,单个文件将变得臃肿。

为什么不让单个页面作为控制器呢?我的意思是,如果你的网站上有一个列出所有注册会员的页面,那么用户导航到的members.php页面将是会员的控制器。这个php文件将从数据库中查询成员列表的成员模型,并将其传递给成员视图。

我可能错过了一些东西,因为我最近才发现MVC,但这个问题一直困扰着我。这种设计不是更可取吗?因为没有一个臃肿的入口文件,所有页面都不直观地调用特定页面的模型和视图,这些都包含、封装并从各自的页面调用。

根据我的经验,拥有一个单一入口点有几个众所周知的优势:

它简化了集中的任务,如资源加载(连接到db或memcache服务器,记录执行时间,会话处理等)。如果您想添加或删除一个集中任务,您只需要更改一个文件,即index.php.

在PHP中解析URL使"虚拟URL"与web服务器上的物理文件布局解耦。这意味着您可以轻松地更改URL系统(例如,出于SEO目的或站点国际化),而不必实际更改脚本在服务器中的位置。

然而,有时使用单一入口点可能会浪费服务器资源。这显然适用于静态内容,但当您有一组具有非常特定目的的请求并且只需要非常少的资源集(例如,它们可能不需要DB访问)时也适用。那么您应该考虑设置多个入口点。我已经为我正在工作的网站做到了这一点。它有一个用于所有"标准"动态内容的入口点,还有一个用于调用公共API的入口点,它们需要的资源少得多,并且具有完全不同的URL系统。

最后一点:如果网站实现得很好,你的index.php不一定会变得臃肿:)

这都是关于DRY的,如果你有很多php文件处理请求,你会有重复的代码。这只会成为维护的噩梦。

查看CakePHP的"主"索引页,https://github.com/cakephp/cakephp/blob/master/app/webroot/index.php

无论应用程序有多大,我都不需要修改它。那么它是如何变得臃肿的呢?

当使用MVC框架时直接深度链接到控制器时,它消除了实现控制器插件或过滤器的可能性,具体取决于您正在使用的框架。拥有单一入口点可以标准化应用程序和模块的引导,并在访问控制器之前执行前面提到的插件。

Zend框架还以路由的形式使用自己的URL重写。在使用Zend框架的应用程序中,我有一个.htaccess文件,其中可能有6行重写的规则和条件。

单个入口点当然有其优点,但是您可以从处理数据库连接、会话等的每个页面顶部的中央必需文件中获得几乎相同的好处。它不臃肿,它符合DRY原则(除了需要行),它分离逻辑和表示,如果你改变文件位置,一个简单的搜索和替换将修复它。

两种我都用过,我不能说其中一种对我的目的来说是更好还是更差。

软件工程师正在影响单点入口范式。

为什么不直接使用单个页面作为控制器呢?

在某种意义上,单个页面已经是Controllers了。

  1. 在PHP中,将会有一些样板代码为每个HTTP请求加载:自动加载器require语句(PSR-4),错误处理程序代码,会话,如果你明智的话,将你的代码的核心包装在一个try/catch中,Throwable作为要捕获的顶部异常。通过集中代码,您只需要在一个地方进行更改!

正确,集中式PHP将至少使用一个require语句(来加载自动加载器代码),但是即使您有许多require语句,它们也都将放在一个文件中,index.php(而不是分散在文档根目录下的许多文件中)。

  • 如果您在编写代码时考虑到安全性,那么您可能会对每个请求进行某些编码检查/清理/验证。使用$_SERVERfilter_input_array()的值?那么你不妨把它集中起来。
  • 底线是这样的。你在每个页面上做得越多,你就越有理由集中代码。

    注意,这种思维方式会导致人们把你的网站看作是一个web应用程序。从web应用程序的角度来看,单点入口是合理的,因为一次性解决的问题只需要在一个地方修改。

    相关文章: