直接手动创建composer.json,按现有结构配置autoload(psr-4或files),避免composer init;第三方库迁移分三步:composer require安装、验证autoload、逐步替换require;注意路径严格匹配、大小写敏感、.gitignore vendor/、保留composer.lock。

旧项目没 composer.json 怎么补?
直接在项目根目录手动新建 composer.json,别用 composer init 交互式生成——它会强制你填一堆没用的元信息,还可能默认设错 type 或 autoload。先写最简结构:
{ "name": "your-vendor/your-project", "type": "project", "require": {}, "autoload": { "psr-4": { "App": "app/" } } }
重点是先对齐现有目录结构,尤其 autoload 部分:如果旧项目用 require_once 'lib/Helper.php' 这种硬路径,就先别急着 PSR-4,改用 files 自动加载:
"autoload": { "files": ["lib/Helper.php", "config/database.php"] }
常见错误:把 vendor/ 目录加进 Git —— 一定加到 .gitignore;还有人把 composer.lock 删了重生成,结果线上环境依赖版本全乱。
第三方库怎么从手动引入切到 Composer?
别删旧文件、别立刻替换 require 路径。分三步走:
- 用
composer require vendor/package安装对应包(比如旧项目用monolog/monologv1 手动解压,就运行composer require monolog/monolog:^1.26) - 确认新包安装后,
vendor/autoload.php已能正确加载类(测试一行new MonologLogger('test')) - 逐步把原来的
require 'lib/monolog/src/...替换成use MonologLogger+new Logger(...)
注意兼容性坑:monolog/monolog v2 不再支持 PHP 7.2,如果旧项目跑在老环境,必须锁死 "monolog/monolog": "^1.26";另外有些包(如 phpmailer/phpmailer)v6 起改用命名空间,但类名没变,容易误以为“能用”,实际调用方式已不同。
autoload 配置写不对,类就永远找不到
PSR-4 映射不是猜路径,是严格匹配命名空间前缀和物理路径。比如代码里写 use FrameworkhttpRequest;,那 autoload.psr-4 必须有 "Framework": "src/",且文件必须在 src/Http/Request.php。常见错:
-
"App": "app/"写成"App": "./app/"(开头的.会导致 Composer 解析失败) - 路径末尾漏掉斜杠,变成
"App": "app"(Composer 会拼出appHttp/Request.php,少了一级目录) - windows 下路径大小写不敏感,但 linux 服务器上
App/和app/是两个目录,映射必须完全一致
验证方法:改完 composer.json 后,执行 composer dump-autoload -o,再用 composer show --path vendor/package 看是否定位到正确位置。
迁移中哪些操作会触发隐性破坏?
最常被忽略的是自动加载顺序和类冲突。Composer 的 files 加载早于 PSR-4,但如果旧项目已有 class_exists('SomeClass') 检查,而该类同时被手动 require 和 Composer files 加载,就会报 Fatal Error: Cannot declare class。
还有两处硬伤:
-
composer install默认只装require,不装require-dev—— 如果旧项目测试工具(如phpunit/phpunit)只写在require-dev,本地跑测试会直接报命令未找到 - 某些老项目用
__autoload()函数,PHP 7.2+ 已废弃,必须删掉或改用spl_autoload_register(),否则和 Composer 自动加载器打架
真正麻烦的从来不是加依赖,而是旧代码里那些没声明、没命名空间、靠 include 顺序存活的类——它们不会报错,但会在某个深夜部署后突然找不到。