下面的(伪)代码都基于 Eloquent ORM。
当然不是完全在 Controller 里写,Controller 和 Model 中间还有一层是负责业务的( Service/Logic ),调用都在 这一层里。
标题只是为了简单描述
一直往 Model 里写 getByxxx 会导致 Model 的方法越来越多…
有人会说写一个
function getByConds(array $conds) () {
if(isset($conds['email'])) {
$query->where('email', $conds['email']);
}
if(isset($conds['xxx'])) {
$query->where('xxx', $conds['xxx']);
}
return $query->get();
}
然后再里面判断 ,那这样和 ->where('email',"[email protected]") 还有区别吗,->where 可以理解为当做也是传递条件而已吧?
function ($column1, $column2, $orderColumn, $orderDirection) {
}
// 是不是等同于
$query->where('column1', 'value1')
->where('column1', 'value2')
->orderBy('orderColumn', 'desc')
->get();
我觉得应该在 Model 里写 scope 把常用的查询条件统一管理即可。文档: https://docs.golaravel.com/docs/5.4/eloquent/#local-scopes
Model 里增加:
functoin scopeVisible($query, $userId) {
return $query->whereRaw('passed = 1 OR user_id = ?', [$userId]);
}
functoin scopeDefaultSort($query) {
return $query->orderBy('weight', 'desc')->orderBy('update_time', 'desc');
}
// 然后查询的时候:
$query->visible($user->id)->defaultSort();
还有,要不要再 Model 里写 create/add 方法,我觉得在 Service/Logic 层统一处理就可以了,没必要放到 Model 里。
<?php
class User
{
public static function add($email, $nickname, $password) {
$user = new User();
$user->email = $email;
// ...
$user->save();
}
}
User::add('email', 'nickname', 'password');
或者动态方法……
class User
{
public function add($email, $nickname, $password) {
$this->email = $email;
// ...
$this->save();
}
}
$user = new User();
$user->add('email', 'nickname', 'password');
不知道大家怎了理解的…
1
mrcn 2017-06-17 13:23:52 +08:00
我觉得应该在控制器直接调用比较好。
如果在 Model 加一个的话相当于只是把 where('email',a)替换成了 whereEmail(a) 没什么意思。 |
2
littleylv 2017-06-17 13:39:50 +08:00
ORM 已经都封装好了,就直接 Controller 里调->where 就好了
|
3
k9982874 2017-06-17 13:43:46 +08:00 via iPhone
我觉得应该在 controller 里写 getByMail。
然而个人认为真正正确的做法应该包装 User 类,解藕和复用。 |
4
wingoo 2017-06-17 13:44:47 +08:00 3
新建 service/logic 层
model 和 controller 中不涉及业务代码 |
5
alwayshere 2017-06-17 13:48:38 +08:00
function getUserInfoByAttr(){}
|
6
devinww 2017-06-17 13:55:52 +08:00
controller 是响应用户操作,调用 service,service 层是写业务代码的
|
7
littleylv 2017-06-17 14:12:56 +08:00
|
8
wingoo 2017-06-17 14:21:13 +08:00
目录结构可以和 model 同级, 调用就是 new 一个调是了
|
9
pantingwen 2017-06-17 14:28:17 +08:00
ORM 优有,直接调用就好了, 如果调用代码比较多,后续还会有其他的地方也会这样调用再封装
|
11
fortunezhang 2017-06-17 14:46:34 +08:00
如果只是简单的查,简单的查,简单的查,那就直接在 controller 里面 where 就行,如果复杂的查,比如用户你要得到用户详细信息,其中还包括用户的发布文章的数量,就在 model 层去做。新增、修改、删除尽量在 model 里面做。
我是这样做的。不对,请轻喷 |
12
wingoo 2017-06-17 14:56:39 +08:00
@zonghua 这样说吧, model 是可用工具生成的, 里面只是生成的代码
controller 中只有接收数据和返回, 中间都调用 service 里的方法 |
13
Immortal 2017-06-17 15:20:53 +08:00
那大佬们 顺便插问一句
现在的 MVC 具体到代码 其实是 Controller Service/Logic Model View 四层 只是我们平时说的时候把 Service 隐式的归到了 Model 吧? 还有那如果一般数据校验什么的都放到 Service 么,Controller 只是个接参数然后传参? |
15
neoblackcap 2017-06-17 15:29:03 +08:00
@Immortal controller 本身是控制业务流程跳转,可以理解成是流水线上的分支开关,model 本身是对应到流水线上的其中一步的业务,不是对应代码的 Model,MVC 里面的 Model 是领域模型,View 就是表象而已,好比你在监控台上看到流水线上每一步的状态是一个绿灯。
|
16
Immortal 2017-06-17 15:32:09 +08:00
@wu1990 那对于纯粹的 api2 个不同的 api,需要返回不同格式的数据格式,但我可以从一个 service 的方法里获取源数据,那么数据格式的整理都是在 controller 还是 service 分两个函数返回?
|
17
wu1990 OP @Immortal 我觉在 controller 里,也可以再加一层负责格式化的,controller 确定需要什么格式,然后将 service 里获取到的数据扔进去格式化
|
18
Immortal 2017-06-17 15:36:33 +08:00
@neoblackcap 大概明白了.那这么理解的话,controller 里会包含点调用逻辑么
比如 `if service.A() { do something }else sevice.B() { do somtthing }` 还是重新定一个 service.C 在里面全部处理掉? |
20
neoblackcap 2017-06-17 15:47:42 +08:00 1
@Immortal 在 Controller 里面做就可以了,你想了解更多,看 https://martinfowler.com/,或者买《企业应用架构模式》
|
21
Immortal 2017-06-17 17:30:53 +08:00
@neoblackcap 非常感谢
|
22
hwding 2017-06-17 18:18:12 +08:00
我也同意新建一个 service 层,组合简单的数据层语句封装起来,对业务层提供更好的封装。
|
23
wdlth 2017-06-17 19:01:04 +08:00
拿 Symfony 来说,可以写在一个类中,变成 Service,在控制器中使用。
|
24
AlwaysBee 2017-06-18 09:51:44 +08:00 via iPhone
service+1,注入到 controller
|
25
meanmachine 2017-06-18 14:26:52 +08:00 via Android
可否把简单 sql 逻辑扔 model, 复杂一点的用 repository
|
26
owenliang 2017-06-18 16:05:32 +08:00
再做一个 service 层,把 ORM 调用封装成 API,这样不同的 controller 可以实现复用。
另外,对 controller 来说,这样只需要组合不同的 service 实现业务,其实也是进一步简化工程复杂度。 |
27
yaxin 2017-06-18 21:49:08 +08:00
如果考虑到之后更改字段或者返回数据处理,还是放 model 处理。我现在就是这样处理的。
|