Php MVC-它在现实世界中是如何工作的?

Php MVC-它在现实世界中是如何工作的?,php,model-view-controller,design-patterns,Php,Model View Controller,Design Patterns,我读过很多关于计算器和温度计的简单MVC示例,但我似乎无法将该模式映射到实际应用程序 假设你有一个更复杂的场景。假设您有一个网站购物车,它要求用户在添加到购物车之前登录。首先,用户看到产品页面(/product/detail)并单击添加项目(/cart/add/207366)。用户尚未登录,因此他们需要访问登录页面(/user/login),然后,对流程保持智能,将他们带到购物车视图(/cart/list)。从那里,他们可以链接回原来的产品详细信息页面继续购物 假设我们有3个数据库表:users

我读过很多关于计算器和温度计的简单MVC示例,但我似乎无法将该模式映射到实际应用程序

假设你有一个更复杂的场景。假设您有一个网站购物车,它要求用户在添加到购物车之前登录。首先,用户看到产品页面(/product/detail)并单击添加项目(/cart/add/207366)。用户尚未登录,因此他们需要访问登录页面(/user/login),然后,对流程保持智能,将他们带到购物车视图(/cart/list)。从那里,他们可以链接回原来的产品详细信息页面继续购物

假设我们有3个数据库表:users、usercart和products。这种情况下的模型是什么?是否将整个流程封装到ShoppingCart模型的addProductToCartFlow函数中?这似乎有点混乱,因为它需要访问users表进行登录/身份验证,并访问products表将产品详细信息/价格拉入购物车

相反,您认为ShoppingCart模型是自包含的,只处理从购物车中添加项目、删除项目等?用户登录的“逻辑”将在其他地方检查:可能在控制器本身?这将使控制器忙于执行相当多的“业务逻辑”,如检查用户是否登录、检查购物车是否为空等,而模型只是成为数据库表的一个漂亮名称

或者,登录或注销的事实本身就是处理此类功能的用户身份验证模型的一部分。或者我们需要一个UserPageState模型来告诉我们用户应该在登录页面、购物车页面还是产品详细信息页面上


在你看来,对于这种情况,什么是最好的MVC设计?

在我的简单站点中,我将为每个表提供一个模型。我可以在控制器中使用任意数量的模型。在更复杂的示例中,客户和购物车没有分开,我有一个模型,可以将它们与了解这两个表的方法结合在一起

有很多模型,非常苗条的控制器,视图中只有HTML。您的控制器应该有很多“if”语句,从控制器中获取结果。您的视图可以有循环和重复结果的“fors”,但没有其他逻辑。除了在视图中,任何地方都没有HTML标记

为了回答您的问题,您可以使用以下模型

  • 用户[进入用户表]
  • 购物车[进入购物车表]
  • 产品表和用户表]
  • 产品[进入产品表]
  • 订单[用户、购物车和产品表(作为一个简单的基本示例)]
  • PageState跟踪站点中用户状态的模型
您有以下控制器

  • 推车
  • 使用者
  • 产品
控制器可能很长,但每个动作都很小,有特定的任务。我认为有一个有10个动作的控制器是可以的,只要这些动作本身是好的和简短的

这些操作调用的模型可能相当长,通常用于说明业务逻辑。我还使用helper类来做一些不是业务逻辑,但仍然很关键的事情。像安全和验证一样思考

还有一大堆的观点。购物车视图、登录框视图、产品摘要视图、产品详细信息视图、每个结账阶段视图、收据视图、HTML格式电子邮件收据视图、类别列表视图、菜单视图、页脚视图。很多很多的观点

您可能希望有一个所有控制器都继承的ApplicationClass,这样您就可以一遍又一遍地做一些事情


您提到了php,所以您有组成模板的视图,但如果您使用ASP,您将有一个包含部分视图的母版页。我不知道您在Ruby或Python中具体做了什么,但它是类似的。

您的模型本质上是业务对象。您将拥有购物车、用户和物品(在大多数情况下,每个客户可能有一辆购物车,但谁说呢?)。您将拥有驱动您的流程的控制器,/cart/add/207366的控制器方法将检查用户是否已授权,如果未授权,则将其传递给控制器进行/login。登录控制器应该足够智能,将正确的信息传递回/cart/add/207366的控制器,然后控制器应该将项目添加到购物车


控制器将调用Cart.AddItem(),但业务逻辑包含在购物车模型中-它可能会查找商品的价格、基于用户的首选客户折扣等。控制器不知道或不关心这一点。控制器确实需要知道用户是否登录(如果这对应用程序很重要),因为这会影响他们的工作(确定要渲染的视图)。他们不需要知道客户是否是首选客户,或者是否持有信用卡,或者其他任何与业务逻辑相关的条件。所有这些都由模型来处理。

我认为您对繁忙控制器的担忧不应该是一种担忧:这是它们的目的。具有添加操作的购物车控制器将依赖用户控制器或身份验证帮助器来查看用户是否已登录。以上两个回答很好地抓住了这一点

另外,我不需要为页面创建另一个模型,而只需要使用一个会话变量或表中的另一个字段。另一个模型实际上只是使事情复杂化,它实际上并不表示需要自包含的实体。你什么时候发现需要访问一堆页面?它实际上只是用户访问登录表单的url字符串,您可以使用会话变量以更少的代码和内存占用的方式跟踪它。只需让addItem()检查它是否已登录,如果未登录,则重定向到登录页面