composer init --no-interaction生成最简composer.json,再手动配置autoload(classmap或psr-4)和require,避免路径错配导致Class not found;autoload改后须运行composer dump-autoload并清opcache。

直接在老项目里跑 composer init 很大概率会搞错 autoload 路径,导致后续 Class not found;正确做法是跳过交互、手动控制结构,再一点点补依赖和自动加载规则。
先跳过交互初始化,别让 composer 自作主张
运行 composer init --no-interaction 生成最简 composer.json,它不会问你包名、描述、autoload 类型这些——因为老项目的目录结构(比如类全在 includes/ 或 lib/)几乎肯定和默认的 src/ + PSR-4 不匹配。此时生成的文件里 autoload 字段是空的,正好留给你自己填。
如果项目里已有 vendor/autoload.php(哪怕只是之前零散 require 过几个包),先别删,留着过渡;composer install 应该能无报错跑通,不写入新文件才算基础结构稳了。
autoload 配置写错,90% 的 Class not found 就在这儿
Composer 不猜路径,只认你写的映射。老项目常见两类结构:
- 传统扁平结构(无命名空间):用
"classmap": ["./includes", "./models"],然后跑composer dump-autoload - 已有命名空间但目录不标准(比如
App对应app/):用"psr-4": {"App\": "app/"},注意 Windows 下反斜杠要双写或统一用正斜杠
改完记得清 opcache(opcache_reset() 或重启 PHP-FPM),否则新映射不生效;如果项目已存在其他 autoloader(如 Zend Framework 的),确保 Composer 生成的 vendor/composer/autoload_psr4.php 里真有你的映射项。
require 和 require-dev 别混着放,上线前 grep 一遍
老项目常把 phpunit、php-cs-fixer 这类工具直接扔进生产环境,也容易漏掉 monolog、guzzlehttp/guzzle 这种实际被入口脚本调用的运行时依赖。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
require:所有会被index.php、定时任务、API 入口执行到的包 -
require-dev:只在本地写代码或 CI 里用的,比如phpunit/phpunit、roave/security-advisories - 不确定时先放
require-dev,上线前grep -r "use .*\PHPUnit\" .或grep -r "new Client" .看有没有实际调用痕迹,再决定是否挪到require
CI/CD 里别碰 composer update,lock 文件必须提交
CI 脚本里只允许用 composer install --no-dev --optimize-autoloader --no-interaction;composer update 会改 composer.lock,破坏可重现性。
composer.lock 必须提交到 Git,它锁定了所有依赖的精确版本;vendor/ 绝对不要提交——CI 慢不是因为没提交 vendor,而是缺缓存(GitHub Actions 用 actions/cache@v4 缓存 ~/.composer/cache 和 vendor/)。
如果 CI 报错 “Package operations: 0 installs…”,检查 PHP 版本是否匹配 composer.json 里的 "php": "^8.1",以及是否漏装扩展(如 Alpine 镜像要 apk add php81-zip)。
最容易被忽略的是:ThinkPHP 6.x 在 Composer 2.5+ 下默认跳过 scripts 钩子,导致 start.php 不生成;得在 composer.json 里加 "allow-plugins": {"topthink/think-installer": true} 显式授权。










