之前团队留下的模型代码都是这样的:
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算了。
不是写在controller里面写 controller就是一个分发url的
验证一般写在model里面
大的项目 model都分层了 model获取中立的数据 如果很复杂的话 model也要分层 用户相关逻辑 可以放在 logic层
然后还可以建立一个service层 一些基本的服务是写在service层里面 service层对应的是驱动层 驱动层比如支付驱动 有支付宝 财付通 网银 等等 然后支付服务就是来链接这些支付驱动的 其实有点类似工厂+策略模式
然后 action执行动作前后 还可以Behavior行为层 定义每个执行动作前后处理的一些事情 比如说写入日志什么的
还有更多的 Widget层等等
转一个我在别的问题(地址:http://segmentfault.com/q/1010000000633144)的回答吧。
每一层都要做,侧重点不同。
我们一般在MVC的C-M之间一定会再加一层Service层(不过也可以理解成是C或M的一部分),这一层是设计为与View和Controller解耦,可以独立剥离出来给外部调用的(API)。
所以,
在View里面,进行比较弱的单个值的合法性校验,
在Controller里面,做外部来的请求数据包的合法性校验和部分用户接口权限校验;
在Service里面做严格的数据合法性校验、业务逻辑约束校验、用户数据权限校验;
在Model里面做数据的物理合法性校验。
另补充:
我们原则上反对在Model层做复杂的业务逻辑校验。
因为这样往往会增加Model里实体对象之间的耦合度,复用性降低。
楼上各位的回答很受教 在这也说说自己的看法
我习惯于两者里面都加验证,但验证不尽相同。
model里的验证不要考虑其他层,只做自己要实现的功能所要求的必须验证;
controller里的验证同样不考虑model层,对自己关心的参数进行验证。
model可能会被多个业务调用,也可能被对个程序员写的代码调用,所以不该去考虑上层提供给自己的保护,把自己保护好就行了。
controller层也类似,下面的model层不是一对一为其服务的,所以不该把自己的验证逻辑推给下面。还是那话,如果半年后一个新接手的程序员,谁知道该为其他业务保留那些验证,这链接太不明显了。
好吧 我的承认我是个很保守等程序员 我承认的安全圈是不跨层的
你这个问题有挂 laravel 标签, 请问是用这个框架么, 若是, 你可以使用 event 来实现, 例如:
你新建一个 event.php(如何自动加载呢???), 示例代码:
Event::listen('eloquent.saving: User', function($model){
});
以上代码在调用内置 org, 如 User::save(), 会自动触发.
其中是 saving可以换成creating, created, updating, updated, deleting, deleted, saving, saved, restoring, restored, auth.attempt, auth.login, auth.logout
我们团队在使用MVC框架时, 都会独立一层Behavior出来, 这一层放业务逻辑.
如果是数据本身进存储的时候需要验证, 那么就在model层做.
如果是因为业务逻辑需要验证, 那么就在behavior层做.例如订单状态的流转,验证非法的状态流转.
如果是和业务逻辑无关的(从controller层转发数据), 那么就在controller层做.
v层由前端或者客户端自行验证,
这样的好处是, behavior可以作为通用逻辑, 让controller有不同的展现方式.特别方便既有web也有接口功能的程序. 坏处是, 需求改动较大的时候, 需要对业务逻辑非常清晰