滚动新闻 →
Windows 11 电池节能模式怎么使用?移动办公时可以这样延长续航 川习会登场 台行政院长:政府将全力因应 热带风暴诺洛已形成 夏威夷大岛将有大型飓风 哈萨克斯坦武装部队军演遇强风 19人卷入大海 composer.json 应该怎么写?PHP 项目的依赖和版本管理基础 中风后遗症?习访美下机 再把彭丽媛当拐杖 开战后首次 泽连斯基:两名朝鲜战俘移交韩国 泽连斯基与芬兰总统签无人机协议 乌提供技术 《史记》为什么不仅是一部历史书 新西兰网络威胁报告:中共网攻最持久 力度最强 习访美遭遇大规模抗议潮 酒店围铁丝网引嘲讽 川习会举行 川普:聚焦超级智能 不放缓AI发展 华为案庭审:电路板送中风波与规避美国制裁 《黄帝内经》中的饮食观念 美延长对中贸易休战 专家:强弱格局高下立判 围棋布局究竟在思考什么 涉向美国AI泄密 DeepSeek和月之暗面被查 为抢松子毒杀松鼠 传东北包山经营者树上挂毒瓜子 柬埔寨破获特大毒品枪支案 逮捕7名中国人 如何培养孩子借用东西后主动归还的习惯 面对窗户拍摄人物应该怎么处理 湖南远洋捕捞到手1亿还不放手 诸多恐怖细节曝光 北京为什么能够成为中国历史上的重要都城 卧室阅读灯应该如何布置 中国传统宴席为什么重视座次 旅行住宿如何兼顾交通和休息 汽车排气冒黑烟应该检查哪些系统 川习会前 美国务院加大力度打击生育旅游 CTB电池车身一体化技术到底是什么 澳洲总理:OpenAI智能体入侵了政府网站 川习会登场 贸易休战延长两个月 纳瓦罗:严防中共洗产地 美启AI查缉 新西兰发布威胁报告 称中共为最大国家级网攻 法官命令川普 暂时恢复CNN等进入白宫14天 双十国庆 串联焰火、晚会呈现台湾多元特色 丢人!中国记者团白宫前争抢位置 争吵推挤 工作手套怎么选择 家庭维修需要哪一种 伊朗联大喊冤 白宫控诉镇压 美财长谈制裁 知名博主遭大连警方跨省抓捕 律师3次会见均被拒 十一前中共大截访 上海七旬访民惨死押送途中

composer.json 应该怎么写?PHP 项目的依赖和版本管理基础

发布时间: 2026-09-24 18:30:01    最后更新: 2026-09-24 18:59:39    阅读:3  约4 分钟阅读     

对于 PHP 项目来说,composer.json 并不是一个简单的“安装软件包列表”,而是整个项目依赖关系的声明文件。项目需要什么 PHP 版本,需要哪些第三方库,生产环境和开发环境分别依赖什么,以及项目应该如何自动加载自己的代码,都可以在这个文件中定义。 理解 composer.json,实际上是在理解现代 PHP 项目是怎样管理依赖的。 一个最简单的 PHP 项目,可以从这样的 composer.json 开始: { "name": "example/my-project", "description": "A PHP application", "type": "project", "require": { "php": "^8.2", "monolog/monolog": "^3.0" }, "require-dev": { "phpunit/phpunit": "^11.0" }, "autoload": { "psr-4": { "App\\": "src/" } } } 这里最重要的是 require 和 require-dev。 require 表示项目运行所需要的依赖。例如一个网站运行时需要日志库、数据库组件或者 HTTP 客户端,这些应该放在 require 中。 require-dev 则用于开发和测试。例如 PHPUnit、PHPStan、PHP_CodeSniffer 等工具通常只在开发环境使用。生产服务器执行 composer install --no-dev 时,可以不安装这些开发依赖。 这两个字段的区别并不是“重要依赖”和“不重要依赖”,而是“生产运行时需要”与“开发阶段需要”。 Composer 的核心机制是依赖解析。 例如项目声明: { "require": { "monolog/monolog": "^3.0" } } 这并不是告诉 Composer “永远安装 Monolog 3.0.0”,而是在告诉 Composer,项目接受符合这个版本约束的 Monolog 版本。 Composer 随后会分析这个包自己的依赖,以及其他直接依赖和间接依赖之间的关系,寻找一个能够同时满足所有版本约束的依赖集合。 这里也需要纠正一个常见误解。 如果项目 A 需要某个库的 ^1.0,项目中的另一个依赖需要同一个库的 ^2.0,Composer 并不会简单地“优先选择最新版本”然后强行安装。 如果两个约束无法同时满足,Composer 通常会报告依赖冲突。解决方案是升级或降级其中一个依赖、调整版本约束,或者寻找兼容的版本组合。 这也是 Composer 和简单复制 PHP 类库最大的区别。 版本号写法尤其重要。 1.2.3 表示一个非常具体的版本约束,而 ^1.2.3 和 ~1.2.3 则允许一定范围内的版本。 对于 Composer 常见的语义版本规则,可以简单理解为: ^1.2.3 允许 1.x 的兼容更新,但不进入 2.0.0 ~1.2.3 允许 1.2.x 的更新,但通常不会进入 1.3.0 1.2.3 只允许这个版本 不过,实际版本约束还受到 Composer 对不同主版本以及零版本号规则的处理影响,所以不能把 ^ 永远理解成“只要小于下一个整数版本”。对于正常遵循语义化版本的库,^1.2.3 最常见的含义是允许 >=1.2.3 <2.0.0。 很多项目最初会把版本写得非常死,例如: "monolog/monolog": "3.0.0" 这样做确实可以限制版本变化,但对于普通应用项目而言,通常没有必要把所有依赖都固定到一个具体版本。Composer 本身就通过 composer.lock 来记录经过解析后的具体版本。 这两个文件的职责不同。 composer.json 描述的是“项目允许使用什么依赖”。 composer.lock 描述的是“这一次解析之后,实际使用了哪些具体版本”。 因此,对于应用程序项目,通常应该把 composer.lock 一起提交到 Git。 例如开发人员运行: composer update Composer 会重新解析依赖,并按照 composer.json 中的约束寻找新的可用版本,然后更新 composer.lock。 而在服务器部署时,通常使用: composer install --no-dev 如果存在 composer.lock,Composer 会根据锁定文件安装已经确定的版本,而不是每次部署都重新选择一套依赖。 这也是为什么不要把“composer.json 改了但 composer.lock 没改”当成正常的版本管理方式。如果修改了依赖声明,通常应该让 Composer 重新解析相关依赖,并把更新后的 composer.lock 一起提交。 如果只想更新某一个依赖,也可以针对具体包执行更新,而不是每次让整个依赖树全部升级。 Composer 的另一个重要功能是自动加载。 现代 PHP 项目通常不需要手动写几十个 require 或 require_once。例如: "autoload": { "psr-4": { "App\\": "src/" } } 表示 App 命名空间下的类可以按照 PSR-4 规则从 src/ 目录自动加载。 项目入口文件通常只需要: require __DIR__ . '/vendor/autoload.php'; 然后就可以使用 Composer 管理的类。 如果修改了 autoload 配置,需要重新生成自动加载文件: composer dump-autoload 生产环境还可以使用: composer dump-autoload -o 优化自动加载。 这里也需要纠正原文中的一个概念:optimize-autoloader 并不是“加快依赖解析速度”。它主要影响的是 Composer 生成和运行时的自动加载机制,而不是 Composer 如何解决版本冲突。 如果希望把自动加载优化作为项目配置的一部分,可以使用: { "config": { "optimize-autoloader": true } } 大型生产项目通常也会在部署时使用优化自动加载。 PHP 版本约束同样应该写进 composer.json。 例如: "require": { "php": "^8.2" } 这意味着项目的运行环境必须满足相应的 PHP 版本要求。 如果开发机器运行 PHP 8.3,而生产服务器只有 PHP 8.1,Composer 就应该尽早暴露这个问题,而不是等程序上线以后才发现语法或者依赖无法运行。 还有一个容易混淆的配置是 config.platform。 正确的结构应该是: { "config": { "platform": { "php": "8.2.0" } } } 而不是把 platform 直接放在 composer.json 顶层。 config.platform 的作用,是告诉 Composer 在依赖解析时按照指定的平台版本进行判断。例如开发人员电脑安装的是 PHP 8.3,但生产环境实际上是 PHP 8.2,那么可以通过 platform 设置让 Composer按照 PHP 8.2 的兼容条件解析依赖。 不过它并不会把电脑上的 PHP 8.3 “变成” PHP 8.2。 这一点非常重要。 如果服务器实际上只有 PHP 8.1,那么 composer.json 写: "platform": { "php": "8.2.0" } 并不会 magically 把 PHP 8.1 升级成 PHP 8.2。它只是改变 Composer 的依赖解析视角。因此部署前仍然必须检查服务器实际 PHP 版本。 Composer 还会把 PHP 扩展当作平台依赖。 例如: "require": { "php": "^8.2", "ext-curl": "*", "ext-mbstring": "*", "ext-gd": "*" } 这里的 ext-curl、ext-mbstring 和 ext-gd 不是普通 Composer 软件包,而是 PHP 环境提供的扩展。 Composer 可以检查它们是否存在,但 Composer 并不会像安装普通 PHP 包一样替你安装这些扩展。 遇到“为什么 Composer 安装失败”的问题时,可以使用: composer show --platform 查看当前 PHP 环境和已经提供的平台依赖。 处理复杂依赖冲突时,composer why 和 composer why-not 非常有用。 例如: composer why monolog/monolog 可以帮助查看为什么项目需要这个包。 而: composer why-not monolog/monolog 3.0.0 可以用于分析为什么某个指定版本无法安装。 这比遇到冲突以后直接删除 composer.lock 或者随便更换一个依赖包更加可靠。 对于私有依赖,也可以在 composer.json 中声明自定义仓库。例如公司内部维护的 Git 仓库: { "repositories": [ { "type": "vcs", "url": "https://gitlab.example.com/team/private-package.git" } ], "require": { "company/private-package": "^1.0" } } 不过 repositories 的作用主要是告诉 Composer 去哪里寻找包,并不等于把 GitLab、GitHub 等服务的账号密码直接写进 composer.json。 认证信息应该通过 Composer 的认证机制、环境变量、CI/CD 的安全凭据等方式处理。不要把访问令牌、密码或者私钥直接提交到 Git 仓库。 Composer 还支持 scripts,可以把项目中的常用操作统一起来。 例如: { "scripts": { "test": "phpunit", "analyse": "phpstan analyse", "cs": "phpcs" } } 之后可以直接运行: composer test composer analyse composer cs 这样团队成员不需要记住一大串命令。 不过,自动执行脚本也需要谨慎设计。尤其是 post-install-cmd、post-update-cmd 这类生命周期脚本,如果里面放置大量修改文件或者执行外部程序的操作,部署环境应该提前审查,避免第三方依赖安装时产生不必要的副作用。 安全方面,现在 Composer 项目应该把依赖审计作为正常开发流程的一部分。 可以运行: composer audit 检查当前依赖是否存在已知安全漏洞。 如果发现漏洞,不能简单理解成“Composer 有问题”。Composer 只是把依赖关系和已知安全公告呈现出来,真正需要处理的是存在问题的第三方包,以及是否存在可以升级到的安全版本。 一个实际项目的 composer.json 通常不需要写得非常复杂。 例如一个普通 PHP 网站可能已经足够: { "name": "mnewstv/website", "description": "MNewsTV website", "type": "project", "require": { "php": "^8.2", "ext-curl": "*", "ext-mbstring": "*" }, "require-dev": { "phpunit/phpunit": "^11.0" }, "autoload": { "psr-4": { "App\\": "src/" } }, "config": { "optimize-autoloader": true, "sort-packages": true } } 然后执行: composer install Composer 会建立 vendor/ 目录,并生成相应的自动加载文件。 通常不需要把 vendor/ 目录提交到 Git,因为它可以根据 composer.json 和 composer.lock 在部署时重新安装。 一个比较规范的 PHP 项目流程通常是这样的: 开发阶段修改 composer.json,然后执行 Composer 命令解析依赖;Composer 更新 composer.lock;开发人员测试程序;composer.json 和 composer.lock 一起提交到版本控制系统;生产环境执行 composer install --no-dev;最后根据部署环境生成优化后的 autoload。 这样,项目依赖就从“某个人电脑上安装了哪些 PHP 包”,变成了可以被代码库明确描述、重复安装和部署的工程配置。 理解 composer.json 最重要的不是记住几十个字段,而是理解几个文件之间的关系:composer.json 负责声明项目需要什么,composer.lock 负责锁定这次解析得到的具体版本,vendor 负责保存实际安装的依赖,vendor/autoload.php 负责把这些类加载进 PHP 程序。 当这几个概念分清楚以后,Composer 就不再只是一个“下载 PHP 插件的工具”,而成为 PHP 项目控制依赖、版本、自动加载、开发工具和部署环境的重要基础设施。对于一个需要长期维护的 PHP 项目来说,真正麻烦的从来不是安装第一个包,而是几年之后依然能够知道这个项目为什么依赖它、依赖哪个版本,以及升级以后会发生什么。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

分享 Facebook | X | WhatsApp | LinkedIn

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP