name是包的唯一标识,必须为vendor/name格式且不含大写字母或下划线;description虽非强制但影响Packagist展示和工具识别,建议控制在120字符内用英文短语。

composer.json 里 name 和 description 字段为什么必须填
不填 name,Composer 会拒绝初始化(报错 "The package name is invalid."),因为它是包的唯一标识,影响 autoloading、Packagist 发布、依赖解析。空 description 虽不报错,但 Packagist 页面会显示警告,且 IDE 或 composer show 命令无法提供上下文信息。
实操建议:
-
name必须是vendor/name格式(如"myorg/myapp"),vendor 名不能含大写字母或下划线 -
description控制在 120 字以内,用英文短语,避免句号结尾(Packagist 自动截断) - 本地开发项目可设
"private": true避免误推送到 Packagist
autoload 配置写错导致类找不到的典型场景
最常见的是路径映射和命名空间不一致。比如 "App\": "src/" 表示所有 App* 类应从 src/ 下加载,但实际文件放在 src/Controllers/ 且类声明为 namespace AppControllers; —— 这没问题;但如果类写成 namespace App; 却放在 src/Controllers/Hello.php,就会触发 Class 'AppHello' not found。
实操建议:
- 优先用
"psr-4",不用"psr-0"(已废弃) - 确保目录结构与命名空间严格对应,
src/App/Service/Logger.php对应namespace AppService; - 修改
autoload后必须运行composer dump-autoload,否则缓存未更新 - 测试是否生效:执行
composer show -s查看 autoload 映射是否列出你的前缀
require 和 require-dev 的边界到底怎么划
核心原则:只有运行时真正需要的包才进 require。比如 phpunit/phpunit 在生产环境完全不需要,放进 require-dev;但 monolog/monolog 如果代码里调用了 new MonologLogger(),就必须在 require 中,否则线上 composer install --no-dev 后直接报错。
实操建议:
-
require-dev只放测试、构建、分析工具(如phpstan/phpstan,friendsofphp/php-cs-fixer) - 框架相关包(如
laravel/framework)属于运行时依赖,永远在require - 如果某个包只在命令行脚本中使用(如数据迁移工具),且该脚本不部署到线上,可考虑
require-dev+ 注释说明 - 执行
composer install --no-dev后,用composer show确认线上环境没多装包
scripts 里 post-autoload-dump 不起作用?检查执行时机
post-autoload-dump 是在生成自动加载文件后触发,不是每次 composer install 都执行——它只在 autoloader 实际被重建时运行(例如修改了 autoload 或安装/卸载了包)。如果你只是改了个 scripts 里的命令却没动依赖或 autoload,它根本不会触发。
实操建议:
- 调试时加日志:
"post-autoload-dump": "echo 'Autoloader rebuilt at $(date)'" - 想每次 install/update 都执行,改用
post-install-cmd或post-update-cmd - 避免在
scripts中调用耗时操作(如生成文档),否则拖慢 CI 流程 - 脚本中引用的二进制文件(如
php-cs-fixer)需确保在vendor/bin/下存在,否则要用完整路径./vendor/bin/php-cs-fixer
Composer 初始化不是填完字段就完事,name 决定包身份,autoload 决定类能不能找到,require 划分直接影响部署成败,而 scripts 的触发条件稍不注意就静默失效。每个配置项背后都有明确的执行链路,改一处得想三处。











