Composer包名必须为vendor/name格式且全小写,autoload路径psr-4需以/结尾,require-dev依赖不参与生产自动加载,platform.php仅影响版本解析。

name 字段必须符合 vendor/name 格式,否则 install 会失败
Composer 通过 name 识别包身份,不是随便起个名字就行。它必须是两段式、小写字母+短横线+数字的组合,中间用斜杠分隔,比如 "myorg/my-package"。如果写成 "my-package" 或 "MyOrg/MyPackage",composer install 会直接报错:Invalid package name "xxx": package names must be lowercase and consist only of letters, digits, underscores, hyphens and forward slashes。
常见误操作:
- 用大写字母或空格(
"MyApp"→ 必须改成"myapp") - 漏掉 vendor 段(
"logger"→ 应为"acme/logger") - 在私有仓库中误用项目目录名代替逻辑包名
autoload 的 psr-4 和 classmap 别混用,路径末尾斜杠决定映射行为
psr-4 是主流自动加载方式,但它的映射路径必须以 / 结尾,否则 Composer 会当成文件而非命名空间前缀处理。例如:"App\\": "src/App/" 合法;而 "App\\": "src/App" 会导致 class App\Foo 去找 src/AppFoo.php,显然不对。
classmap 适合加载非标准结构的类(如旧代码、第三方脚本),它扫描指定目录下所有 .php 文件并生成类名到路径的静态映射。注意:classmap 不支持命名空间推导,只认 class XXX 声明。
实操建议:
- 新项目统一用
psr-4,路径结尾加/ - 需要加载
functions.php这类纯函数文件?写进autoload.files数组 - 开发中改了
autoload配置后,记得运行composer dump-autoload -o生效
require 和 require-dev 的依赖隔离不只影响安装,还影响 autoload 生成
require 中的包会被所有环境加载,其 autoloading 规则也会合并进主项目的自动加载映射;而 require-dev 中的包(如 phpunit/phpunit)默认不会参与生产环境的 autoload 构建——除非你执行了 composer install --no-dev,否则它们仍会出现在 vendor/autoload.php 里。
关键点在于:即使没启用 --no-dev,require-dev 包的类也不会被自动加载,除非你显式 require 它们的文件,或者它们自己注册了 autoload.files。所以别指望 phpunit 的类能在生产代码里直接 new。
容易踩的坑:
- 把测试工具(如
fakerphp/faker)误放require,导致生产环境多加载几十个类 - 在
require-dev里放了运行时必需的库(比如某个 CLI 工具依赖的解析器),结果线上命令跑不起来 - CI 环境忘记加
--no-dev,导致打包体积膨胀、启动变慢
config.platform PHP 版本设错,会导致本地能装、CI 报错
config.platform.php 是用来“欺骗” Composer 的:告诉它“我实际运行的 PHP 版本是 X.X”,哪怕你本地是 8.2,也能强制让 Composer 解析出兼容 7.4 的依赖版本。但它不是万能补丁——如果某个包在 composer.json 里写了 "php": "^8.0",而你设 "platform": {"php": "7.4"},Composer 会直接拒绝安装,因为平台约束比包自身要求更严格时,它优先信任包声明。
真实问题场景:
- 本地开发用 PHP 8.2,但服务器是 7.4 → 必须设
platform.php,且所有依赖都得支持 7.4 - CI 使用容器化 PHP 8.1,但忘了同步
platform值,导致依赖解析出高版本包,运行时报Attribute语法错误 -
platform只影响依赖版本选择,不影响实际运行时行为——PHP 7.4 运行不了 PHP 8.0 语法,这点没法绕过
composer.json 后,最好用 composer validate 过一遍,再在目标 PHP 版本下跑一次 composer install --no-dev 确认闭环。










