PHP单体仓库:代码组织与最佳实践
在现代PHP开发中,代码的有效组织问题日益凸显。传统的多仓库(multirepo)方法存在诸多缺陷:版本同步复杂、配置重复以及重构困难。而单体仓库(monorepo)作为一种替代策略,将所有相关项目、包和库存储在单一仓库中。本文将探讨如何组织PHP单体仓库、使用哪些工具以及需要注意哪些陷阱。
什么是单体仓库,PHP项目为何需要它?
单体仓库是一个包含多个项目或包的单一代码存储库。在PHP领域,典型的例子是Laravel,它在单一仓库中包含了框架、认证包、队列包、邮件包及其他组件。
PHP项目的主要优势:
- 简化重构 — 对某个包的修改会立即对所有依赖组件可见,无需单独发布和更新每个包的版本。
- 版本一致性 — 所有包使用相同版本的依赖项,从而避免类型冲突。
- 统一CI/CD — 所有组件共享单一构建流水线,简化跨包变更的测试。
- 改善协作 — 开发者可查看整个项目代码,便于代码审查并保持统一的编码标准。
然而,单体仓库并非适用于所有场景。如果项目之间关联性弱或发布周期不同,多仓库可能更合适。对于组件集成紧密的中大型PHP项目,单体仓库往往是更优选择。
PHP单体仓库的结构
合理的结构是成功单体仓库的基础。以下以包含核心(core)、多个模块和测试的项目为例,展示典型组织方式。
my-php-monorepo/├── packages/│ ├── core/│ │ ├── src/│ │ │ └── CoreService.php│ │ ├── tests/│ │ └── composer.json│ ├── module-auth/│ │ ├── src/│ │ ├── tests/│ │ └── composer.json│ └── module-payment/│ ├── src/│ ├── tests/│ └── composer.json├── apps/│ ├── api/│ │ ├── public/│ │ ├── src/│ │ └── composer.json│ └── console/│ ├── src/│ └── composer.json├── tests/│ └── IntegrationTest.php├── composer.json (根目录)├── phpunit.xml.dist├── .gitignore└── README.md关键组织原则:
- 包分离(packages) — 每个包拥有独立的
composer.json,包含名称、自动加载和依赖项。 - 应用(apps) — 入口点(API、控制台命令),用于整合各包。
- 根目录composer.json — 包含单体仓库的元配置。
配置根目录composer.json
为使单体仓库正常工作,需配置根目录composer.json,使各包在本地可用,而无需发布到Packagist。
{ "name": "my-company/my-monorepo", "type": "project", "require": { "php": "^8.1", "my-company/core": "*", "my-company/module-auth": "*", "my-company/module-payment": "*" }, "autoload": { "psr-4": { "MyCompany\\\\": "packages/" } }, "repositories": [ { "type": "path", "url": "packages/*", "options": { "symlink": true } } ], "scripts": { "```