composer 仅管理单服务依赖与类加载,不处理服务通信;每个微服务须独占 git 仓库、composer.json 和 composer.lock,共享逻辑须发布为私有包,autoload 必须严格收敛至本服务命名空间。

Composer 不拆分代码库,也不管理服务间通信;它只确保每个独立服务的依赖装得对、类加载不越界、生产环境不混入开发工具。
每个微服务必须有自己独立的 composer.json 和 composer.lock
你不能把所有服务塞进一个仓库、共用一个 composer.json —— 那不是微服务,是带命名空间的单体。真实微服务的起点是物理隔离:
- 每个服务对应一个 Git 仓库(如
user-service、order-service) - 每个仓库根目录下有专属
composer.json,require只写本服务真正运行时需要的包(比如guzzlehttp/guzzle用于调其他服务,ext-pdo_pgsql用于自己连库) -
composer.lock必须提交,且只服务于本仓库 —— 服务 A 锁monolog/monologv2.10,服务 B 锁 v3.5,完全合法;共享 lock 文件会直接导致 CI 安装失败 - CI 流程中必须用
composer install --no-dev --optimize-autoloader --no-interaction,禁用update—— 后者会重写 lock,破坏部署可重现性
共享逻辑不能靠 autoload 跨目录加载,得抽成私有 Composer 包
常见错误:在 user-service/composer.json 的 autoload.psr-4 里写 "Shared\": "../shared-dto/src/"。这会让自动加载器从别处拖代码进来,彻底破坏服务边界。
正确做法是发布为独立包:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 新建 Git 仓库
acme/shared-dto,含自己的composer.json,name字段设为acme/shared-dto - 打语义化 tag(如
v1.2.0),Satis 才能索引;别用dev-main直接 require,否则 CI 构建时反复 clone 失败 - 在各服务中加仓库源:
"repositories": [{"type": "vcs", "url": "https://git.example.com/acme/shared-dto"}],再composer require acme/shared-dto:^1.2 - 本地开发调试可用
path类型临时替代,但上线前必须切回私有仓库地址
require-dev 放错位置,线上就可能暴露调试入口或加载失败
require-dev 不是“可有可无”,而是明确的运行时禁区:
-
phpunit/phpunit、phpstan/phpstan、symfony/maker-bundle必须只在require-dev—— 它们不该出现在生产镜像里 -
symfony/flex是典型陷阱:它不参与运行,但会自动注入配置,必须放require-dev;否则 CI 中 recipe 注入可能污染生产环境 - Docker 构建漏掉
--no-dev,symfony/debug-bundle就会被加载,/_profiler暴露堆栈和环境变量 - 某些包(如日志驱动切换)若靠 dev/require 拆分来实现行为差异,会导致线上功能异常 —— 应优先通过配置控制,而非依赖位置
私有仓库不必上 Private Packagist,Satis 就够用
中小团队没必要为内部 DTO 包搭整套 Private Packagist。Satis 足够轻量可控:
- 写一个
satis.json,声明要索引的 Git 仓库(支持 GitHub/GitLab/Gitea) - 执行
php bin/satis build satis.json web/,生成静态packages.json - 用 Nginx 托管
web/目录即可,无需 PHP 运行时 - 注意:Satis 不代理下载,dist 包仍从原始 Git 地址拉取,确保 CI 能访问内网 Gitea 等地址
最易被忽略的一点:所有服务的 autoload.psr-4 映射必须严格收敛到自身命名空间,例如 "App\": "src/",绝不能写成 "Acme\": "vendor/acme/*/src" —— 否则自动加载器会在 vendor 里乱翻,服务隔离形同虚设。










