本文目录导读:

- 核心原则
- 方案一:经典分层架构(MVC变体)— 适用于大多数Web项目
- 方案二:领域驱动设计(DDD)— 适用于复杂业务系统
- 方案三:模块化/微服务单体(Modular Monolith)
- 方案四:命令行CLI工具或包(Packagist)类库
- 推荐的命名空间映射(基于方案一)
- 几个常见坑与建议
- 总结建议
在PHP项目中,合理的类文件目录规划对于项目的可维护性、可扩展性以及团队协作至关重要,以下是基于现代PHP开发实践(尤其是遵循PSR-4自动加载规范)的几种主流规划方案。
核心原则
- 遵循PSR-4自动加载:命名空间(Namespace)与目录结构一一对应,这是Composer支持的标准,也是现代PHP框架的基石。
- 单一职责:每个类文件只做一件事。
- 按功能/业务分层:将不同职责的类放入不同的顶层目录。
经典分层架构(MVC变体)— 适用于大多数Web项目
这是最常见、最成熟的结构,适合API、CMS、企业应用等。
project-root/
├── app/
│ ├── Controllers/ # 控制器:处理HTTP请求,返回响应
│ │ ├── Admin/ # 按模块分
│ │ ├── Api/ # API控制器
│ │ └── Web/ # Web页面控制器
│ ├── Models/ # 模型:数据库表映射、业务实体
│ ├── Services/ # 服务层:核心业务逻辑(如订单计算、支付处理)
│ │ ├── OrderService.php
│ │ └── PaymentService.php
│ ├── Repositories/ # 仓储层:数据访问抽象(可选但推荐)
│ │ ├── UserRepository.php
│ │ └── ProductRepository.php
│ ├── Middleware/ # 中间件:请求过滤(Auth, Log, CORS)
│ ├── Exceptions/ # 自定义异常类
│ └── Providers/ # 服务提供者(框架相关,如Laravel)
├── config/ # 配置文件
├── database/ # 数据库迁移、种子数据
├── public/ # Web入口(index.php)
├── resources/ # 视图模板、语言文件、静态资源
├── routes/ # 路由定义
├── storage/ # 日志、缓存、文件上传
├── tests/ # 单元测试、功能测试
│ ├── Unit/
│ └── Feature/
├── vendor/ # Composer依赖
├── bootstrap/ # 框架启动文件
├── .env # 环境变量
└── composer.json
核心目录说明:
- app/Models:存放与数据库表直接对应的实体类(
User.php,Order.php)。 - app/Services:关键层,将“协调多个模型”或“复杂计算”的代码从Controller中抽离,例如
CheckoutService调用CartService,InventoryService,PaymentGateway。 - app/Repositories:隔离数据源,如果将来需要从MySQL切换到Redis或MongoDB,只需修改Repository的实现,Controller和Service无需改动。
- app/Controllers:保持“瘦控制器”,只负责参数校验、调用Service、返回结果。
领域驱动设计(DDD)— 适用于复杂业务系统
当业务逻辑非常复杂(如ERP、金融系统、电商核心)时,按业务领域而非技术功能划分。
project-root/
├── src/
│ ├── Context/ # 上下文:按业务领域划分
│ │ ├── Ordering/ # 订单域
│ │ │ ├── Domain/ # 领域模型、值对象、领域事件
│ │ │ │ ├── Model/
│ │ │ │ ├── Events/
│ │ │ │ └── Spec/
│ │ │ ├── Application/ # 应用服务、DTO
│ │ │ ├── Infrastructure/ # 仓储实现、外部API适配
│ │ │ └── UserInterface/ # 控制器、API端点
│ │ ├── Payment/ # 支付域
│ │ │ └── ...
│ │ └── Inventory/ # 库存域
│ ├── Shared/ # 共享内核(通用工具类、基类)
│ └── ...
├── tests/
├── config/
└── ...
优点:高内聚低耦合,每个领域独立演进,适合微服务架构的代码库。 缺陷:初学时略显过重。
模块化/微服务单体(Modular Monolith)
将大型应用拆分为多个独立的“模块”,每个模块内部有自己的完整分层,这在框架中很常见。
project-root/
├── modules/
│ ├── User/
│ │ ├── Controllers/
│ │ ├── Models/
│ │ ├── Services/
│ │ ├── Repositories/
│ │ ├── Tests/
│ │ └── routes.php
│ ├── Product/
│ │ └── ...
│ └── Order/
│ └── ...
├── app/ # 全局公共代码
│ ├── Providers/
│ ├── Exceptions/
│ └── ...
├── config/
├── routes/
└── public/
优点:代码组织清晰,团队可独立负责不同模块,未来容易拆分为微服务。
命令行CLI工具或包(Packagist)类库
如果你在开发一个Composer包或CLI工具,结构应尽可能简单、可复用。
project-root/
├── src/
│ ├── Command/ # 命令类
│ ├── Exception/ # 异常
│ ├── Helper/ # 辅助函数
│ ├── Interface/ # 接口
│ └── YourPackage.php # 入口类
├── tests/
├── config/
├── bin/ # CLI入口脚本
├── composer.json
└── README.md
推荐的命名空间映射(基于方案一)
在composer.json中配置PSR-4的自动加载,一般指向app/或src/目录:
{
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
在这个配置下,类文件app/Services/OrderService.php的命名空间应为namespace App\Services;。
几个常见坑与建议
- 不要把所有逻辑都塞进Model:Model(如
User)不应包含发送邮件、生成PDF等与自身无关的逻辑,这会形成“肥胖模型”。- ✅ 推荐:将特定逻辑放入
Service或Action类。
- ✅ 推荐:将特定逻辑放入
- 避免过度嵌套:如
app/Http/Controllers/Api/V1/User/Auth/AuthController.php,当目录层级超过4层时,可考虑用模块化(如modules/Auth/)来扁平化。 - 使用
traits/目录:如果发现多个类共享相同的方法,可以考虑创建一个app/Traits/目录存放trait文件。 - 参考成熟框架:Laravel、Symfony、ThinkPHP等框架已经给出了很好的范例,如果使用框架,尽量遵循其默认约定(如Laravel的
app/Http/Controllers),不要随意重构。
总结建议
- 小项目(<10个文件):直接放在
lib/或src/根目录下即可。 - 中型项目(API、CMS):优先选择分层架构(Controller → Service → Model/Repository),清晰易维护。
- 大型复杂业务系统:可考虑DDD或模块化。
- 关键步骤:务必在项目初期配置好
composer.json的PSR-4自动加载,确保目录结构变动时能自动生效。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播