以前的PHP项目,管理依赖是一件很痛苦的事。需要用什么库,就去官网下载zip包,解压到项目目录里,然后手动require/include。如果库有更新,要重新下载替换;如果库依赖其他库,还要手动下载依赖的依赖。依赖一多,管理起来非常混乱,版本冲突、文件丢失、更新困难等问题层出不穷。

Composer的出现,彻底改变了PHP的依赖管理方式。Composer是PHP的依赖管理工具,类似于Node.js的npm、Python的pip、Ruby的bundler。它能帮你自动管理项目的依赖——声明项目需要哪些库,Composer会自动下载这些库以及它们的依赖,并管理版本。

Composer现在已经成为PHP开发的标配,几乎所有主流的PHP框架(Laravel、Symfony、Yii、CodeIgniter等)和PHP库都支持Composer。掌握Composer的使用,是每个PHP开发者的必备技能。

但很多人只是简单地用composer installcomposer require,没有发挥Composer的全部能力。今天分享Composer的最佳实践,帮你更好地使用Composer。

安装Composer

Composer的安装很简单。

Linux/Mac:

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Windows: 下载Composer-Setup.exe,运行安装程序,会自动配置环境变量。

安装完成后,运行composer --version,如果显示版本号,说明安装成功。

国内用户建议配置国内镜像,加速下载:

composer config -g repo.packagist composer https://packagist.phpcomposer.com

或者用阿里云的镜像:

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

composer.json配置

composer.json是Composer的配置文件,用JSON格式,描述了项目的依赖和其他配置。一个基本的composer.json:

{
    "name": "myproject/myapp",
    "description": "My PHP Application",
    "type": "project",
    "require": {
        "php": ">=7.0",
        "monolog/monolog": "^1.0",
        "guzzlehttp/guzzle": "^6.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^5.0",
        "squizlabs/php_codesniffer": "^2.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "scripts": {
        "test": "phpunit",
        "cs-check": "phpcs"
    }
}

关键字段说明:

  • name:项目名称,格式是"作者/项目名"
  • description:项目描述
  • type:项目类型,常见的有library(库)、project(项目)、metapackage(元包)、composer-plugin(插件)
  • require:生产环境依赖,项目运行需要的库
  • require-dev:开发环境依赖,只在开发和测试时需要的库(如测试框架、代码检查工具),生产环境不会安装
  • autoload:自动加载配置
  • scripts:自定义脚本命令

版本约束

Composer的版本约束很灵活,常用的约束方式:

  • 精确版本:1.2.3,只安装1.2.3版本
  • 范围:>=1.0 <2.0,安装1.0到2.0之间的版本(不包括2.0)
  • 通配符:1.0.*,安装1.0.x的最新版本
  • 赋值运算符:~1.2,等价于>=1.2 <2.0~1.2.3等价于>=1.2.3 <1.3
  • 脱字符:^1.2.3,等价于>=1.2.3 <2.0(不改变最左边非零数字)

推荐用脱字符(^),它遵循语义化版本(SemVer),允许补丁版本和次要版本更新,不允许主要版本更新(主要版本可能有不兼容变更)。比如^1.2.3允许更新到1.3.0、1.9.9,但不允许更新到2.0.0。

自动加载

Composer提供了强大的自动加载功能,支持PSR-0、PSR-4、classmap、files四种方式。

PSR-4:推荐使用,按命名空间映射目录。

"autoload": {
    "psr-4": {
        "App\\": "src/",
        "App\\Models\\": "src/models/"
    }
}

这样,App\Controllers\UserController类会自动从src/Controllers/UserController.php加载。

PSR-0:旧的标准,不推荐,按命名空间的每个部分映射目录。

"autoload": {
    "psr-0": {
        "App_": "src/"
    }
}

classmap:扫描指定目录,生成类映射表,性能好,但新增类需要重新生成。

"autoload": {
    "classmap": ["src/", "lib/"]
}

files:手动指定需要加载的文件,适合全局函数文件。

"autoload": {
    "files": ["src/helpers.php"]
}

修改autoload配置后,需要运行composer dump-autoload重新生成自动加载文件。

常用命令

Composer的常用命令:

  • composer init:交互式创建composer.json
  • composer install:根据composer.json和composer.lock安装依赖(第一次安装会生成composer.lock)
  • composer update:更新所有依赖到最新版本(符合版本约束),更新composer.lock
  • composer update package/package:更新指定的包
  • composer require package/package:添加依赖并安装
  • composer require --dev package/package:添加开发依赖
  • composer remove package/package:移除依赖
  • composer dump-autoload:重新生成自动加载文件
  • composer show:列出所有已安装的包
  • composer show package/package:查看指定包的信息
  • composer outdated:查看有更新的包
  • composer search keyword:搜索包
  • composer validate:验证composer.json是否合法
  • composer self-update:更新Composer自身

composer.lock的作用

composer.lock是Composer生成的锁文件,记录了所有依赖的确切版本号。它的作用是保证团队所有成员和生产环境使用完全相同的依赖版本,避免"在我机器上能跑"的问题。

使用原则:

  • composer.lock应该提交到版本控制(Git/SVN),团队所有成员共用
  • 生产环境部署时,用composer install(根据composer.lock安装确切版本),不要用composer update
  • 只有在需要更新依赖时,才在本地运行composer update,测试通过后提交新的composer.lock
  • 不要手动修改composer.lock

优化自动加载

生产环境可以优化Composer的自动加载,提升性能:

composer dump-autoload --optimize

--optimize会把PSR-4/PSR-0的自动加载转换成classmap,减少文件查找,提升性能。生产环境部署时建议加上这个参数。

也可以在composer.json中配置,让install和update时自动优化:

"config": {
    "optimize-autoloader": true
}

私有仓库

如果公司有内部的PHP包,不想公开,可以搭建私有Composer仓库。常用的方案:

  1. Satis:Composer官方的静态仓库生成工具,简单轻量
  2. Toran Proxy:Composer官方的代理和私有仓库,功能更强大
  3. Private Packagist:Composer官方的商业私有仓库服务
  4. Artifactory:JFrog的制品仓库,支持Composer
  5. GitLab/GitHub:可以直接用Git仓库作为Composer源

在composer.json中配置私有仓库:

"repositories": [
    {
        "type": "composer",
        "url": "https://packagist.mycompany.com"
    }
]

脚本功能

Composer的scripts功能可以定义自定义命令,方便执行常用的脚本:

"scripts": {
    "test": "phpunit",
    "cs-check": "phpcs src/",
    "cs-fix": "phpcbf src/",
    "post-install-cmd": [
        "php artisan migrate"
    ],
    "post-update-cmd": [
        "php artisan migrate"
    ]
}

运行自定义脚本:

composer test
composer cs-check

Composer还支持事件钩子,在install/update等事件前后自动执行脚本,如post-install-cmd、post-update-cmd、pre-install-cmd等。

团队协作最佳实践

团队使用Composer的最佳实践:

  1. composer.json和composer.lock都提交到版本控制
  2. 新成员克隆项目后,运行composer install安装依赖
  3. 添加依赖用composer require,不要手动修改composer.json
  4. 更新依赖在本地操作,测试通过后提交composer.lock
  5. 生产环境用composer install --no-dev --optimize-autoloader部署
  6. 定期运行composer outdated查看有更新的依赖,及时更新
  7. 配置国内镜像,加速下载
  8. 不要把vendor目录提交到版本控制(在.gitignore中忽略)

常见问题

Q:composer install和composer update有什么区别? A:composer install根据composer.lock安装确切版本,如果没有composer.lock,就根据composer.json安装并生成lock。composer update会更新所有依赖到符合约束的最新版本,并更新composer.lock。生产环境用install,不要用update。

Q:依赖版本冲突怎么办? A:当多个依赖要求同一个包的不同版本,且版本范围不重叠时,会报版本冲突。解决方法:升级或降级某个依赖,或者用composer why package/package查看为什么需要这个包,分析冲突原因。

Q:内存不足怎么办? A:Composer有时候会消耗大量内存,尤其是更新大量依赖时。可以增加PHP内存限制:php -d memory_limit=-1 composer update,或者升级Composer到最新版本(新版本内存管理更好)。

Q:怎么移除不需要的依赖? A:用composer remove package/package,会自动从composer.json移除并卸载。不要手动删除vendor目录和修改composer.json。

总结

Composer是PHP开发的必备工具,它让PHP的依赖管理变得简单、规范、高效。掌握Composer的最佳实践——合理的版本约束、规范的自动加载、正确使用composer.lock、优化自动加载、团队协作规范——能让你的PHP项目开发更高效、更稳定。

如果你还在用手动下载库的方式管理依赖,赶紧试试Composer吧。它会改变你的PHP开发方式。