讨论 Web 开发中 PHP 项目的合理分层

有时候写着写着代码,就会觉得自己写的一团糟。觉得这儿也不合理,那儿也不合理。强迫症更是为了很小的一些东西纠结半天。

在此只是讨论一下代码整体目录结构的分层合理性,并不是什么标准,也只是说一些自己的见解和大家一起讨论。

controller

 当我们收到一个请求的时候,会先进入controller,那么这层应该做什么事情呢?我个人认为controller层应该做3件事情

1. 接收并验证参数的基本类型正确性和参数的必须性
2. 调用logic,可以调用多个logic
3. 返回响应

我们应该在这一层验证参数的基本正确性,而且只允许调用logic,可以调用多个logic进行配合完成最终的业务处理。至多写个if else调用不做其它处理。

logic

logic层,分发控制逻辑层,只能被controller调用,这层应该做3件事情

1. 进一步验证参数的正确性,比如是否存在数据,或者其他复杂逻辑的验证
2. 调用service层,可以调用多个service实现具体业务,比如调用serviceA得到结果,再传入serviceB获取数据。
3. 返回结果

每个controller都应该对应一个logic,而且方法一一对应,这层我们用来进一步验证参数的合法性,以及控制service层,使得彼此配合完成业务。这层只能调用service。而不能相互调用。

service

service层,具体的业务层,这层应该书写详细的逻辑处理,

1. 书写具体逻辑,一般可以是被多次调用的。这层需要灵活的解耦,以便于logic调用。
2. 调用model层,model层应该只能被service调用。
3. 返回结果

service只能被logic调用,不能彼此调用

lib

现在还有一个问题就是,service层可能会相互依赖,比如serviceA依赖serviceB,或者同时logicA也依赖serviceB,那么service是不应该互相调用的。我个人想法是在service层建一个lib。我们可以把serviceA依赖serviceB的方法提取出来,写一个Trait亦或者是一个类。总之service的共用方法提取到lib里面。这样完成解耦。

model

model我觉得没有争议,就是和数据库打交道。
最终目录结构
Controller
Logic
Service
    --Lib
Models

总体流程就是 controller调用logic,logic调用service,service的彼此依赖提取到lib中,service调用model。这样配合完成最终的处理。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 10
Summer

我来抛砖引玉哈。

不建议分层太多,整太复杂。

KISS —— keep it simple and stupid.

一个优秀的项目结构就是你写的时候很舒服、方便,一两年过去了,需要修改代码,还可以轻松定位到。

分层太多,真正写代码时,一些简单的逻辑会让你无法决定放在哪里。

之前有个同事,觉得 Model 里不该写业务逻辑,就弄了个 Repository 模式。几个月后过去了,发现他还是在 Model 层里还是写业务逻辑,询问的结果是:他用了一段时间的 Repository 模式后,后面觉得 Repository 太费劲,没有直接 Model 来着方便,就又回到 Model 层写逻辑。可是项目推进很快,原有代码没写测试不敢轻易重构,导致整个项目陷入混乱。

不要过多设计,保持简单是最佳实践。

2个月前 评论
Jiangqh 2个月前
lyxxxh 2个月前
欧皇降临 2个月前
Summer

我来抛砖引玉哈。

不建议分层太多,整太复杂。

KISS —— keep it simple and stupid.

一个优秀的项目结构就是你写的时候很舒服、方便,一两年过去了,需要修改代码,还可以轻松定位到。

分层太多,真正写代码时,一些简单的逻辑会让你无法决定放在哪里。

之前有个同事,觉得 Model 里不该写业务逻辑,就弄了个 Repository 模式。几个月后过去了,发现他还是在 Model 层里还是写业务逻辑,询问的结果是:他用了一段时间的 Repository 模式后,后面觉得 Repository 太费劲,没有直接 Model 来着方便,就又回到 Model 层写逻辑。可是项目推进很快,原有代码没写测试不敢轻易重构,导致整个项目陷入混乱。

不要过多设计,保持简单是最佳实践。

2个月前 评论
Jiangqh 2个月前
lyxxxh 2个月前
欧皇降临 2个月前

controller=> service=> model,多了确实就很烦躁

2个月前 评论
kis龍 2个月前
Colorado 2个月前

c->s->m就够了吧 其他的感觉多余

2个月前 评论

c->s->m 或者,c->m ,或者 c。
如果只是一个数据的创建,一个c就够了,稍微复杂点的 c->m,有各种复杂情况的 c->s->m

2个月前 评论

c->s->m,最佳体验 :kissing_heart: :kissing_heart:

2个月前 评论
congcong (楼主) 2个月前

Logic+Service 典型tp3.2项目

2个月前 评论

controller=> service=> model
我感觉这个就够了

  • controller 业务+逻辑

  • service 提供数据,比如 UserService::user(1); 获取用户ID 1 的用户信息, 可以添加自定义字段

  • model 模型,访问数据库

PS: 同一个逻辑会在多个地方使用吗? 大多数逻辑只用1次吧?

2个月前 评论

开发思路应当这样

  1. 先使用最简单的 mvc 写下去
  2. 遇到 或 预判 到 重复逻辑 , 则提取到 service 或 logic 层
  3. 不要为了分层而分层 , 每层应该在它最需要的时候出现
  4. service 或 logic 应该只专注业务 , 数据验证和过滤不应在此层进行 , controller 传递过来的数据必须是可靠地
2个月前 评论

@liu126 同意

基本和你一样。mvc ,有重复的编写lib公共类,供其它类调用。
如果逻辑太长,也提取出来。

2个月前 评论

原来还有lib,我一般都是直接依赖注入解耦(违背你说的service不能相互调用)

2个月前 评论
congcong (楼主) 2个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!