模型或控制器中的动态SQL

时间:2013-10-20 13:15:26

标签: php mysql model-view-controller

我知道所有逻辑等都应该放在控制器中,但我有一个SQL语句,其中某些部分由另一个函数的返回值决定。

在我的模特中:

    $cols = 'products.id, name, currencies.symbol, basePrice';
    $m = new AuthController();
    if($m->moduleExists('Sales'))
    {
      $cols .= 'lastSold';
    }

或者在我的控制器中将SQL作为参数传递给模型?

    $cols = 'products.id, name, currencies.symbol, basePrice';
    if($this->moduleExists('Sales'))
    {
      $cols .= 'lastSold';
    }

1 个答案:

答案 0 :(得分:1)

<强> tldr;版本

考虑到关注点和分离的分离,与持久性最佳相关的代码不应包含与特定系统的子模块相关的业务逻辑(该逻辑是否属于模型部分的控制器,MVC,或者控制器部分,或程序员引入系统的任何其他部分)。应该避免从持久层到业务逻辑的访问以维持解耦,而应该优先考虑访问持久层的业务逻辑的另一种方式。

<强>理由

在您的模型中,您应该放置与您的视图中显示的内容无关的代码,即模块是否存在,或者是否授权拥有此类模块。您的模型中的代码应该可以由子系统,其他系统,与您的视图无关的任何内容或甚至与特定用例相关的业务逻辑使用。它应该具有与系统范围相关的逻辑。虽然授权似乎具有系统范围,但应特别小心处理,因为它可能导致设计脆弱。在控制器级别使用它更灵活。想象一下,试图支持多种授权技术。

根据授权或视图标准修改查询将无法维护稳定的独立模型。

所以是的,它应该进入你的控制器。

控制器是否是与视图或特定业务逻辑相关的控制器(与用例相关或与系统相关,即授权控制器)现在可以具有更改查询的授权标准,并且将来可能会出现一些其他标准与特定用例或子系统域有关。这意味着控制器可以更改,您甚至可以使用特定方式引入访问相同模型的不同控制器。

<强>实施

有很多方法可以解决您的问题。如,

  • 从您的持久层检索数据的完整版本,即所有列,并让您​​的控制器根据逻辑确定要显示的内容,即用户的授权
  • 在您的持久层中有多个查询独立于您的其他逻辑,即queryProducts,queryProductsWithTotals,queryProductsWithLastSoldDate,然后让您的业务逻辑控制器决定调用哪个
  • 在持久层中创建一个通用函数,接受cols(如果可能的话,非魔术值),以便根据其他控制器具有的逻辑参数化可以查看的内容并相应地调用此函数
  • 一般来说,最好避免将sql查询放在不同的地方,因为维护变得困难。但是,可能会出现这种情况,并且很大程度上取决于系统的设计,即每个用例调用持久层以便执行的自定义查询的业务控制器。