简介
- Composer是PHP的一个依赖管理工具,他允许你申明项目所依赖的代码库,他会你的项目中为你安装他们。
- 依赖管理
- Composer不是一个包管理器,它涉及packages和libraries,它在每个项目的基础上进行管理
- Composer 将这样为你解决问题:
- 一个项目依赖于若干个库
- 其中一些库依赖于其他库
- 你申明你所依赖的东西
- Composer会找出那个版本的包需要安装,并安装它们(将它们下载到你的项目中)
- 系统要求
- Composer需要5.3.2+以上版本
安装
*nix
- 下载
局部安装:这种方式是直接下载一个PHP的归档文件直接使用;
php -r "readfile('https://getcomposer.org/installer');" | php
或者指定安装
curl -sS https://getcomposer.org/installer | php -- --install-dir=bin
全局安装:将此文件放进系统PATH目录,你就能全局访问他,甚至在使用的时候都可以不用使用php前缀
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
windows安装
安装程序下载: Composer-SetUp.exe;下载安装后默认帮你设置好环境变量,因此你就可以在全局使用composer命令;
手动安装:下载composer.phar文件并设置好环境变量PATH
cd C:\Users\Administrator\bin
php -r "readfile('https://getcomposer.org/installer');" | php
在composer.phar同级目录下新建composer.bat文件;.bat的文件名称将是你使用composer的别名
echo @php "%~dp0composer.phar" %*>composer.bat
关闭窗口进行测试
composer -V
基本用法
composer.json:项目安装
要在项目中使用composer,你需要一个composer.json文件。此文件包含了一些项目的依赖和一些其他的元数据
关于require Key
- composer.json做的第一件事就是申明你项目的依赖
{
"require" : {
"monolog/monolog" : "1.0.*",
}
}
require关键词申明依赖,例如包monolog/monolog对应的包版本1.0.*
包名称:包名称有供应商名称和项目名称构成。通常容易产生相同的项目名称,而供应商名称的存在解决了名称冲突的问题。他允许两个不同的人创建同样名为json的库,而他们将被名为为 igorw/json和seldaek/json
包版本:前面的monolog指定的版本为1.0.*。这表示 任何从1.0开始的开发分支它都会匹配,它会匹配1.0.0、1.0.20。
版本约束可以用不同的方法来指定
名称 | 实例 | 描述 |
---|---|---|
确切的版本号 | 1.0.2 | 指定包的确切版本号 |
范围 | >=1.0 >=1.0,<2.0 >=1.0,<1.1|>=1.2 |
通过有效的比较操作符来指定有效的版本范围 ,有效的运算符号:>、>= 、< 、<=、!= 你可以定义多个范围,用逗号隔开,将会被处理成and ,一个管道符号| 将被处理成or , and的优先级高于or |
通配符 | 1.0.* | 通过通配符* 来指定一种模式。1.0.*与 >=1.0,1.1 等效 |
赋值运算符 | ~1.2 | 对于遵循语义化的项目非常有用,~1.2相当于>=1.2,<2.0 |
下一个重要版本(波浪号运算符)
~ 最好用例子来解释: ~1.2 相当于 >=1.2,<2.0,而 ~1.2.3 相当于 >=1.2.3,<1.3。正如你所看到的这对于遵循 语义化版本号 的项目最有用。一个常见的用法是标记你所依赖的最低版本,像 ~1.2 (允许1.2以上的任何版本,但不包括2.0)。由于理论上直到2.0应该都没有向后兼容性问题,所以效果很好。你还会看到它的另一种用法,使用 ~ 指定最低版本,但允许版本号的最后一位数字上升
稳定性
默认下只有稳定发行的版本才被考虑在内,如果你想活得RC、beta、alpha或dev版本
关键词 | 解释 |
---|---|
alpha | 内部测试版,α是希腊字母的第一个,表示最早的版本,一般用户不要下载这个版本,这个版本包含很多BUG,功能也不全,主要是给开发人员和 测试人员测试和找BUG用的。 |
beta | 公开测试版。β是希腊字母的第二个,顾名思义,这个版本比alpha版发布得晚一些,主要是给“部落”用户和忠实用户测试用的,该版本任然存 在很多BUG,但是相对alpha版要稳定一些。这个阶段版本的软件还会不断增加新功能。如果你是发烧友,可以下载这个版本 |
RC | 全写:Release Candidate(候选版本),该版本又较beta版更进一步了,该版本功能不再增加,和最终发布版功能一样。这个版本有点像最终发行版之前的一个类似 预览版,这个的发布就标明离最终发行版不远了。作为普通用户,如果你很急着用这个软件的话,也可以下载这个版本 |
stable | 稳定版。在开源软件中,都有stable版,这个就是开源软件的最终发行版,用户可以放心大胆的用了 |
RTM | 商业软件;称为Release to Manufacture。工厂版。改版程序已经固定,就差工厂包装、光盘印图案等工作了 |
OEM | 商业软件;称为Release to Manufacture。工厂版。改版程序已经固定,就差工厂包装、光盘印图案等工作了 |
EVAL | 商业软件;评估版。就是有30或者60天等使用期限的版本 |
RTL | 商业软件;Retail.(零售版),这个版本就是真正发售的版本,有漂亮的包装、光盘、说明书等东西和高昂的价格 |
Composer.lock-锁文件
安装依赖后,composer会将安装的确切版本写入到composer.lock文件,这个文件将锁定更改项目的特定版本
composer.lock的作用: 任何建立项目的人都会下载与指定版本相同的依赖。持续集成服务器、生产环境、你团队中的开发人员、每件事、每个人都使用相同的依赖,从而减少潜在的错误对部署的影响。即使你独自开发的项目,在六个月内重新安装项目时,你也可以放心的继续工作,即使从那时起你的依赖以及发布了很多新的版本。
注意:提交项目时应将你的comoser.json和composer.lock文件都提交到你的项目库里,因为composer install命令将会检查composer.lock文件是否存在,如果存在将下载指定版本;不会使用composer.json文件,composer.lock文件存在将会被忽略,如果不存在将会读取Composer.json文件创建新的Composer.lock文件,如果你要更新你的依赖,请使用update
命令。这将会获取最新匹配的版本(根据你Composer.json文件),并将版本更新进Composer.lock文件
php composer.phar update
如果你只想更新部分依赖,你可以通过设置白名单的方式实现
php composer.phar nupdate monolog/monolog
自动加载
对于库的自动加载信息,Composer生成了一个vendor/autoload.php文件,引入这个文件将会获得自动加载的支持
require 'vendor/autoload.php';
引入了自动加载文件,很容易的就可以使用第三方库,例如:你的项目依赖monolog
$log = new Monolog\Logger('name');$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');
你可以在Composer.json文件autoload字段增加自己的autoloader,例如:
{
"autoload": {
"psr-4": {"Acme\\","src/"}
}
}
Composer将注册一个PSR-4的autoload到Acme的空间
你可以定义一个命名空间到目录的映射,此时src会在你的项目根目录,与vendor文件夹同级。例如 src/Foo.php文件就会加载Acme\Foo类;
注意:映射格式为你定义的命名空间名称,必须对应到你申明的命令空间根目录地址;例如上面的定义的Acme命令空间映射的位置是
- 案例:monolog项目
Composer.json配置的自动加载
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2L8uLSe8-1596550893770)(en-resource://database/516:1)]
文件格式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-biu55WkH-1596550893773)(en-resource://database/518:1)]
命名空间:命名空间都是一项目名称开始申明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ikrINWW5-1596550893776)(en-resource://database/524:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1OwktvO1-1596550893779)(en-resource://database/522:1)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P8vO5sSD-1596550893780)(en-resource://database/526:1)]
引入autoload.php这个文件将autoloader的实例,你可以将的返回之存储在变量中来加载更多的命名空间,例如:
$loader = require 'vendor/autoload.php';
$loader->add('Acme\\Test\\', __DIR__);
Composer提供了自己的autoloader,如果你不想使用它,你可以只引入 vendor/composer/autoload_*.php
文件,它返回一个关联数组,可以通过自己的关联数组配置自己的autoloader 示例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VN5Xqi33-1596550893782)(en-resource://database/528:1)]
库(资源包)
每个项目都是一个包
只要你有composer.json文件在你的项目中,那么整个目录就是一个包。当你添加一个require到你的项目中,你就是在创建一个依赖于其他库的包。你的项目和库之间的区别是,你的项目是一个没有名字的包
为了使它成为可安装的包,你需要给你的项目取一个名称。通过composer.json
的name
来定义
{
"name": "acme/hello_world",
"require": {
"monolog/monolog": "1.0.*"
}
}
这种情况下项目的名称为acme/hello_world
,其中acme是供应商的名称,供应商的名称必须填写
注意: 如果你不知道那什么作为供应商的名称,那么使用你github上的用户名是个不错的选择。虽然包名不区分大小写,但是惯例是使用小写字母,并使用连接字符作为单词分割
平台软件包
Composer 将那些已经安装在系统上,但不是由Composer安装的包视为一个虚拟的平台软件包,这包含PHP本身,PHP扩展和一些系统库。
PHP
表示用户的PHP版本要求,你可以对其作出限制,例如限制>=5.4.0。如果需要64位版本的PHP,你可以使用php-64bit
hhvm
代表的是HHVM(也就是HipHop vitual Machine)运行环境的版本,允许你设置一个版本的限制,例如:’>=2.3.3’ext-<name>
可以帮你指定需要的PHP扩展(包括核心扩展)。通常PHP拓展的版本可以是不一致的,将他们的约束版本约束为*
是一个不错的注意。一个PHP扩展包的例子:包名字可以写成ext-gdlib-<name>
允许对PHP库的版本库进行限制。以下是可供使用的名称curl、iconv、icu、libxml、openssl、pcre、uuid、xsl
你可以是用composer show --platform
来查看可用的软件包列表。
指明版本
- 你需要一些方法来指明自己开的包的版本,当你在packagist上发布自己的包,它能够从VCS(git、svn、hg)的信息推断出包的版本,因此你不必指明包的版本号, 并且也不建议这样做。 请看下面标签和分支来了解版本号是如何被提取的
如果你要手动创建并且明确的指定它,你只需要添加一个version
字段:
{
"version": "1.0.0"
}
注意: 你应该尽量避免手动设置版本,因为标签的只必须与标签的名像匹配
标签
对于每一个看起来像版本号的标签,都会相应的创建一个包的版本。他应该符合‘X.Y.Z’或者’vX.Y.Z’的形式, -patch,-alpha、beta、-RC
这些后缀都是可选的,在后缀之后也可以在跟上一个数字
下面是有效标签名称的几个例子
- 1.0.0
- v1.0.0
- 1.10.5-RC1
- v4.4.4beta2
- v2.0.0-aplha
- v2.0.4-p1
注意: 即使你的标签带有前缀
v
,由于在require
一个版本的约束时是不允许这种前缀的,因此v
将被省略(例如:标签v1.0.0
将创建1.0.0
的版本)
分支
对于每一个分支,都会相应的创建一个包的开发版本。如果分支看起来很像一个版本号,那么将创建一个如同{分支名}-dev
的版本号。例如一个分支2.0
将产生一个2.0.x-dev
的包版本(加入了.*
是出于技术的原因,以确保它被识别为一个分支,而2.0.x
的分支名称也是允许的,同样也会被转化为2.0.x-dev
)。如果分支开起来不像一个版本,它将会创建dev-{分支名}
形式的版本号。例如master
将产生一个dev-master
的版本号
下面是一些分支版本的示例:
- 1.x
- 1.0(equals 1.0.x )
- 1.1.x
注意: 当你安装一个新的版本时,它将自动从
source
中拉取
别名
它表示一个包版本的别名。例如你可以为dev-master
设置一个别名1.0.x-dev
,这样就可以通过require 1.0.x-dev
来得到dev-master
版本的包
为什么使用别名
当你使用 VCS 资源库,你将只会得到类似于这样的版本号:从分支发布的标签获取,它看起来像 2.0 或 2.0.x。比较特殊的是,对于你的 master 分支,你会得到一个最新提交的 dev-master 版本。对于你的 bugfix 分支,你会得到一个最新提交的 dev-bugfix 版本。以此类推,这些特殊的版本标识可以用来获取最新的分支源码。
如果你的 master 分支使用标签发布了 1.0 系列版本,即 1.0.1、1.0.2、1.0.3 等等,任何依赖它的资源包都可能会使用 1.0.* 这个版本约束。
如果有人想要最新的 dev-master 版本,他们将会碰到一个问题:另一些依赖它的包可能使用了 1.0.* 这个版本约束,因此在 require 这个开发版本时将会产生冲突,因为 dev-master 不符合 1.0.* 的约束。这时,就可以使用别名。
- 分支别名
dev-master 指向一个在你 VCS 项目上的主分支。有些用户会想要使用最新的开发版本,这是相当常见的情况。因此,Composer 允许你别名你的 dev-master 版本为一个 1.0.x-dev 的版本号。这是通过在 composer.json 文件中的 extra 下指定 branch-alias 字段来完成的:
{
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
}
}
此处的分支别名必须是以dev-
开头(不可比较的版本名称),对应的别名是可比较的开发版本名称(即以数字开头,并以.x-dev
结束)。branch-alias
所引起的分支必须存在,对于dev-master
你需要在master
分支上提交它。
其结果是,任何人都可以使用1.0.*
版本约束来得到dev-master
版本。
为了定义分支别名,你必须是需要别名的包的所有者。如果你想别名一个第三方包,而又不想fork
它到自己的版本库,可以使用行内别名
行内别名
分支别名是非常适合主开发的分支,但是使用他们的前提,你需要有对源码的控制权限,并且你要提交别名的修改到你控制的版本库
使用情景:
- 当你只想在本地项目修复一些依赖包的bug修正时,你可以直接在
require
和require-dev
字段中直接使用你需要的包,例如:你找到了monolog/monolog的一个bug时,symfony/monolog-bundle
require了monolog/monolog
,并约束了版本限定为1.*
;因此你可以这样做,将github上的克隆一份,并在bugfix
的分支上修复它,然后使用这个包的操作如下
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/you/monolog"
}
],
"require": {
"symfony/monolog-bundle": "2.0",
"monolog/monolog": "dev-bugfix as 1.0.x-dev"
}
}
它将在你的GitHub上获取monolog/monolog
的dev-bugfix版本并将其命名为1.0.x-dev
。
注意:
如果要对一个资源包使用行内别名,这个别名(as 的右边)必须能够使用版本约束。as左边的部分在这之后将被丢弃。因此,如果 A 依赖 B 而 B 又依赖 monolog/monolog 且版本约束为 dev-bugfix as 1.0.x-dev,那么安装 A 时将使用 B 的版本约束,并识别为 1.0.x-dev,此时必须真实存在一个“分支别名”或“1.0 系列分支”。否则就必须在 A 的 composer.json 文件中再次定义行内别名。
注意: 应该尽量避免行内别名,特别是对已经发布的包。如果你发现了一个 bug,请尝试将你的修复合并到上游分支。这将避免使用你资源包的用户出现问题。
锁文件
始终针对同一个版本进行测试。任何时候,这个锁文件都只会对你的项目产生影响
发布vcs(线上版本控制系统)
一旦你有一个包含composer.json
文件的存储库在线上的版本控制系统(列如:git) ,你的库就可以被composer所安装。在这个例子中,我们将 acme/hello-world 库发布在 GitHub 上的 github.com/username/hello-world 中。
现在测试这个 acme/hello-world 包,我们在本地创建一个新的项目。我们将它命名为 acme/blog。此博客将依赖 acme/hello-world,而后者又依赖 monolog/monolog。我们可以在