验证写在controller还是model里?
之前团队留下的模型代码都是这样的:
public function getcount($where){
if(!empty($where)){
$db->where($where);
}
$db->from($tablename);
return $db->count_all_results();
}
————————
function edit($tid,$data){
$db->where('tid', $tid);
return $db->update($tablename, $data);
}
MODEL里这样写这样的纯粹的增删改查有什么优点?
验证部分究竟应该放在哪里比较好
?
请阐明其中的道理和厉害关系。
之前可能有人看的太快导致的误解,上述代码的model里面那个empty并不算真的判断,关于$where参数,是需要严格按照数据库对应的字段拼装,而model里并没有任何判断,严重依赖控制器喂给它正确的参数。
项目经理铁定要求在控制器处理验证,所以现在的控制器里有数量可观的巨型函数(需要调用model的地方都超过150行了),而且格式基本近似。
举个例子,现在的情况是:
view提交表单到controller,在那里验证表单,呼叫model,并为model拼装数组参数(如同上面代码里那样)。
看到后来新的答案里有些说的情况比较模糊,比如“复杂逻辑”这样还是没法明确。所以,我再细化一下问题:
现在的model里仅仅是转发了一下sql的增删改查的基本操作,在控制器里调用这些model的时候,我必须严格根据数据库里的字段名来拼装$data数组,这就基本等同于没有model,还不如控制器里直接拼sql算了。
laravel codeigniter php thinkphp mvc
Answers
验证代码应该写在服务层
那么这里就要对mvc解析一下
v层由于变动频繁,而又非服务端程序员必理层,故此完全可以独立出来,以配置方式分发。
m层是数据层,那就单纯处理数据就得了,不要添加其他没必要的处理,导致混乱。
c层是调度层,对用户传递过来的url作对应处理,这里跟权限有关,登陆和没登陆的操作。
那么这里少了一层,就是逻辑层logic。建议添加l层
l层处理逻辑,提供服务,提供关闭和开放的决定。
而验证建议使用c层的权限判断,而权限判断是一个服务,让l层提供。
这样设计的好处不少
v层对外,只提供配置文件,让有关程序员,只配置文件即可。
其次m层可以独立出来一个专用服务器,也可安排专门处理这块的程序员负责。
c层处理用户调度,掌握业务层和用户体验的程序员最适合。
l层实际就是服务层,链接业务层和数据层,版本控制,启用和关闭服务。
对新来的同事,验证服务有问题,可以让他重写一个验证服务,不必重写原来的验证的服务。这种修改方式,应该是养成习惯,不修改,只增加。
对于楼主要解决的验证写在controller还是model里,这个问题,取决于架构问题。
如果就是mvc,那么是否有不同角色权限,如果不是,可以选择新建一个基础c,里面配置一个用户验证。如果有不同角色权限,完全可以继承这个基础c,重写即可。
建议在c层验证,个人认为,用户进来,进入调度范围,就必须要正确到达目的地,否则,我不知道调度的作用为何。
如果没有设计缺陷,就放在c层验证吧,概念更清晰一些。
c层验证,l层逻辑
你这个问题有挂 laravel 标签, 请问是用这个框架么, 若是, 你可以使用 event 来实现, 例如:
你新建一个 event.php(如何自动加载呢???), 示例代码:
Event::listen('eloquent.saving: User', function($model){
这里做验证, 附加操作逻辑等, 最后 return $model 就好
});
以上代码在调用内置 org, 如 User::save(), 会自动触发.
其中是 saving可以换成creating, created, updating, updated, deleting, deleted, saving, saved, restoring, restored, auth.attempt, auth.login, auth.logout
不是写在controller里面写 controller就是一个分发url的
验证一般写在model里面
大的项目 model都分层了 model获取中立的数据 如果很复杂的话 model也要分层 用户相关逻辑 可以放在 logic层
然后还可以建立一个service层 一些基本的服务是写在service层里面 service层对应的是驱动层 驱动层比如支付驱动 有支付宝 财付通 网银 等等 然后支付服务就是来链接这些支付驱动的 其实有点类似工厂+策略模式
然后 action执行动作前后 还可以Behavior行为层 定义每个执行动作前后处理的一些事情 比如说写入日志什么的
还有更多的 Widget层等等
楼上各位的回答很受教 在这也说说自己的看法
我习惯于两者里面都加验证,但验证不尽相同。
model里的验证不要考虑其他层,只做自己要实现的功能所要求的必须验证;
controller里的验证同样不考虑model层,对自己关心的参数进行验证。
model可能会被多个业务调用,也可能被对个程序员写的代码调用,所以不该去考虑上层提供给自己的保护,把自己保护好就行了。
controller层也类似,下面的model层不是一对一为其服务的,所以不该把自己的验证逻辑推给下面。还是那话,如果半年后一个新接手的程序员,谁知道该为其他业务保留那些验证,这链接太不明显了。
好吧 我的承认我是个很保守等程序员 我承认的安全圈是不跨层的
我们团队用的Java,现在的验证方法是这样的:
比如
User
, 使用各种
JSR303
在实体上搞好校验规则和校验message,封装好
check
方法(这个是最基础的,不管怎么样都需要验证的,一般我们使用的是Hibernate-Validator实现),如果类型和逻辑比较多,还可以衍生出
updateCheck()
,
saveCheck()
,如果校验没有通过就抛出参数错误异常;我在做的过程中其实想到这一点没有必要另外些check方法,完全可以使用JSR303的group分组来实现不同业务的需求验证(这点没有具体实践,只是现在有这么一个想法)
然后在controller那里注解调用对应的check方法作为验证就行了,验证方法如果抛出异常了,直接在catch里面做相应的处理返回.