Maison  >  Questions et réponses  >  le corps du texte

php - 验证写在controller还是model里?

之前团队留下的模型代码都是这样的:

public function getcount($where){//$where是数组,严格对应DB字段!
   if(!empty($where)){
    $db->where($where);
   }
   $db->from($tablename);
   return $db->count_all_results(); 
}

public function edit($tid,$data){//$data是数组,严格对应DB字段!
  $db->where('tid', $tid);
  return $db->update($tablename, $data);
}

当我在控制器里调用MODEL的时候,要严格按照数据库schema来拼装参数。

MODEL里这样写这样的纯粹的增删改查有什么优点?
验证部分究竟应该放在哪里比较好
请阐明其中的道理和厉害关系。

之前可能有人看的太快导致的误解,上述代码的model里面那个empty并不算真的判断,关于$where参数,是需要严格按照数据库对应的字段拼装,而model里并没有任何判断,严重依赖控制器喂给它正确的参数。

项目经理铁定要求在控制器处理验证,所以现在的控制器里有数量可观的巨型函数(需要调用model的地方都超过150行了),而且格式基本近似。

举个例子,现在的情况是:
view提交表单到controller,在那里验证表单,呼叫model,并为model拼装数组参数(如同上面代码里那样)。

看到后来新的答案里有些说的情况比较模糊,比如“复杂逻辑”这样还是没法明确。所以,我再细化一下问题:

现在的model里仅仅是转发了一下sql的增删改查的基本操作,在控制器里调用这些model的时候,我必须严格根据数据库里的字段名来拼装$data数组,这就基本等同于没有model,还不如控制器里直接拼sql算了。

天蓬老师天蓬老师2723 Il y a quelques jours1675

répondre à tous(19)je répondrai

  • 怪我咯

    怪我咯2017-04-10 15:02:26

    不是写在controller里面写 controller就是一个分发url的

    验证一般写在model里面

    大的项目 model都分层了 model获取中立的数据 如果很复杂的话 model也要分层 用户相关逻辑 可以放在 logic层

    然后还可以建立一个service层 一些基本的服务是写在service层里面 service层对应的是驱动层 驱动层比如支付驱动 有支付宝 财付通 网银 等等 然后支付服务就是来链接这些支付驱动的 其实有点类似工厂+策略模式

    然后 action执行动作前后 还可以Behavior行为层 定义每个执行动作前后处理的一些事情 比如说写入日志什么的

    还有更多的 Widget层等等

    répondre
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 15:02:26

    首先,你们团队的代码是正确的,输入验证是放在model层。model是与数据交互的,按照“与谁关系最密切就与谁处理”的原则,数据验证应该由model层处理,controller只是起到一个转发的作用,与逻辑数据有关的不应该放在这里面。
    关于道理和厉害关系:
    说实话,这个没啥理论,就是一辈辈的开发者们经验所得。你可以将验证放在controller里面,然后开发一个大型应用试一下就知道了。
    跟设计模式差不多,为什么要这样设计?完全就没有道理,完全是无数次实验之后得出的结论。然后这些不好的地方自然就成了好的道理。
    以后遇到这种没有定性的问题,你自己实验一下,自然就知道哪里放哪里好了。

    正所谓知道了什么不好,才真正的知道什么才是好。人生亦是如此

    répondre
    0
  • 巴扎黑

    巴扎黑2017-04-10 15:02:26

    转一个我在别的问题(地址:http://segmentfault.com/q/1010000000633144)的回答吧。

    每一层都要做,侧重点不同。

    我们一般在MVC的C-M之间一定会再加一层Service层(不过也可以理解成是C或M的一部分),这一层是设计为与View和Controller解耦,可以独立剥离出来给外部调用的(API)。

    所以,
    在View里面,进行比较弱的单个值的合法性校验,
    在Controller里面,做外部来的请求数据包的合法性校验和部分用户接口权限校验;
    在Service里面做严格的数据合法性校验、业务逻辑约束校验、用户数据权限校验;
    在Model里面做数据的物理合法性校验。

    另补充:
    我们原则上反对在Model层做复杂的业务逻辑校验。
    因为这样往往会增加Model里实体对象之间的耦合度,复用性降低。

    répondre
    0
  • 高洛峰

    高洛峰2017-04-10 15:02:26

    验证写在model里面会比较好。
    如果你写在controller里,如果另外一个controller也需要用到相同的验证,怎么办?还得复制粘贴相同的代码,复用性就没有体现出来了,如果你写在model里面那就不一样了。

    répondre
    0
  • PHP中文网

    PHP中文网2017-04-10 15:02:26

    权限验证放到 controller
    数据验证放到 model

    répondre
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 15:02:26

    楼上各位的回答很受教 在这也说说自己的看法
    我习惯于两者里面都加验证,但验证不尽相同。
        model里的验证不要考虑其他层,只做自己要实现的功能所要求的必须验证;
        controller里的验证同样不考虑model层,对自己关心的参数进行验证。
    model可能会被多个业务调用,也可能被对个程序员写的代码调用,所以不该去考虑上层提供给自己的保护,把自己保护好就行了。
    controller层也类似,下面的model层不是一对一为其服务的,所以不该把自己的验证逻辑推给下面。还是那话,如果半年后一个新接手的程序员,谁知道该为其他业务保留那些验证,这链接太不明显了。
    好吧 我的承认我是个很保守等程序员 我承认的安全圈是不跨层的

    répondre
    0
  • 高洛峰

    高洛峰2017-04-10 15:02:26

    我们团队用的Java,现在的验证方法是这样的:
    比如User, 使用各种JSR303在实体上搞好校验规则和校验message,封装好check方法(这个是最基础的,不管怎么样都需要验证的,一般我们使用的是Hibernate-Validator实现),如果类型和逻辑比较多,还可以衍生出updateCheck(),saveCheck() ,如果校验没有通过就抛出参数错误异常;我在做的过程中其实想到这一点没有必要另外些check方法,完全可以使用JSR303的group分组来实现不同业务的需求验证(这点没有具体实践,只是现在有这么一个想法)
    然后在controller那里注解调用对应的check方法作为验证就行了,验证方法如果抛出异常了,直接在catch里面做相应的处理返回.

    répondre
    0
  • 阿神

    阿神2017-04-10 15:02:26

    model里处理复杂的逻辑,controller里处理交互控制转发。这是基本的MVC模式吧,要说好处大概就是逻辑处理与输入输出相互分开

    répondre
    0
  • 怪我咯

    怪我咯2017-04-10 15:02:26

    表单验证等没有通用性的验证建议放在controller,一些复杂和通用的业务逻辑建议下沉到model层去实现。

    répondre
    0
  • 高洛峰

    高洛峰2017-04-10 15:02:26

    model变化的频率和验证变化的频率差别太大,就此一点就注定他们不能在一起

    répondre
    0
  • Annulerrépondre