PHP项目目录结构怎么规划

wen PHP项目 1

PHP项目目录结构怎么规划?一份面向现代Web开发的黄金标准指南


目录导读

  1. 为什么目录结构决定了项目的生死
  2. 经典分层架构:MVC不是银弹,但它是起点
  3. 现代PHP项目目录规划实战(基于Composer + PSR-4)
  4. 模块化 vs 单体:如何根据业务规模选择
  5. 常见反模式:这些坑90%的开发者都踩过
  6. 问答环节:解决你最后的5个疑惑
  7. 从今天起重构你的项目骨架

为什么目录结构决定了项目的生死

PHP项目目录结构怎么规划

在PHP开发中,目录结构往往被视为“低级问题”,但谷歌和必应的爬虫对代码可读性毫无兴趣,而真正的风险在于团队协作成本后期维护噩梦,一个混乱的目录会让新成员花费3天才能找到修改一个接口的位置,而规范的目录能让CI/CD流程、单元测试、依赖管理无缝衔接,更关键的是,PSR-4自动加载规范(PHP-FIG制定)要求目录结构与命名空间严格对应,这直接决定了你的代码能否被Composer生态高效拉取。

经典分层架构:MVC不是银弹,但它是起点

大多数PHP框架(Laravel、Symfony、CodeIgniter)默认采用MVC,但目录划分绝不仅仅是将ControllerModelView三个文件夹堆在一起,核心在于依赖方向:Controller依赖Service,Service依赖Repository,Repository依赖Model,一个规范的目录必须体现这种层级:

project/
├── app/
│   ├── Http/           # 控制器、中间件、请求表单
│   ├── Services/       # 业务逻辑层(核心)
│   ├── Repositories/   # 数据访问层
│   └── Models/         # Eloquent/Doctrine实体
├── config/             # 环境配置
├── database/           # 迁移、填充、工厂
├── routes/             # 路由定义
├── resources/          # 视图、语言包、静态资源
├── tests/              # 单元/功能测试
└── public/             # Web根目录(唯一对外暴露)

现代PHP项目目录规划实战(基于Composer + PSR-4)

以Laravel 11 + PHP 8.3为例,推荐更细粒度的切割:

  • Domain层(业务核心):app/Domain/Order/Entities/Events/Exceptions/,将订单逻辑放入独立文件夹,而不是堆在Models里。
  • Application层app/Application/UseCases/ 存放“生成订单”或“取消订单”这类用例类,每个类仅负责一个动作。
  • Infrastructure层app/Infrastructure/Persistence/ 负责外部API、缓存、数据库实现。

关键优化技巧:在composer.json中明确映射命名空间:

"autoload": {
    "psr-4": {
        "App\\Domain\\": "app/Domain/",
        "App\\Application\\": "app/Application/"
    }
}

这样,new App\Domain\Order\OrderEntity会自动寻址到对应文件,部署时执行composer dump-autoload -o即可生成优化加载器。

模块化 vs 单体:如何根据业务规模选择

  • 小团队/快速原型:按技术层划分即可,但必须在app/下保留Services独立层,否则业务逻辑会泄漏到控制器里。
  • 中大型项目:强烈推荐模块化DDD,示例:src/Modules/Billing/,内含Application/Domain/Infrastructure/UI/四个子目录,这种结构让多个团队可以并行开发不同模块,且模块间通过接口通信,降低耦合。

常见反模式:这些坑90%的开发者都踩过

  • 把所有模型放在一个Models文件夹:当项目有300个表时,你会疯掉。
  • 在控制器里写SQL查询:这破坏了分层,导致无法单元测试。
  • 直接使用/lib/vendor存放业务代码vendor只应放第三方依赖,业务代码扔进去会因composer更新被覆盖。
  • 忽略tests目录的对应结构:测试必须与应用目录镜像,否则无法自动化定位测试类。

问答环节:解决你最后的5个疑惑

  • Q1:每个目录都需要index.php吗?
    A:不需要,只有public/需有入口文件,其他目录建议放置.gitkeepREADME.md,防止空目录被版本控制系统忽略。

  • Q2:我可以用app/而不是src/吗?
    A:可以,但必须与composer.json中的PSR-4映射保持一致,框架默认app/,但src/更中立,适合非框架核心代码。

  • Q3:配置文件应该放哪里?
    A:config/目录,但禁止将密钥、数据库密码写入文件,推荐使用环境变量(.env)并在.gitignore里排除。

  • Q4:静态资源(CSS/JS)何时放在public/外?
    A:当需要经过压缩、版本哈希时,可放在resources/assets/,由前端构建工具(如Vite、Webpack)编译后输出至public/build/

  • Q5:如何在现有项目中安全重构目录?
    A:一次只移动一个命名空间,先修改composer.json,执行composer dump-autoload,运行完整测试,若没有测试……那就先写测试,再重构!

从今天起重构你的项目骨架

目录结构不是艺术,而是工程纪律,它决定了你的代码是“一次性创作”还是“可长期演进的资产”,请打开你的终端,执行mkdir -p app/Domain app/Application app/Infrastructure tests/Domain,然后给你的业务逻辑安个家。好的目录让你在凌晨3点被叫醒处理紧急事故时,能5分钟内定位问题——这就是它存在的唯一意义。


(本文基于PSR-4规范、Laravel最佳实践及十余年PHP社区经验综合撰写,适用于任何现代PHP框架。)

抱歉,评论功能暂时关闭!