Composer是一个非常流行的PHP包依赖管理工具,它已经取代了PEAR包管理器。PHP开发者掌握Composer是很有必要的。对于用户来说,Composer非常简单,所需的代码将通过一个简单的命令传递。将包下载到vendor目录,开发者就可以导入包使用了。关键在于你项目定义的composer.json,它可以定义项目所依赖的包(可能有多个),而依赖的包可能会依赖其他包(这就是组件的好处),你不用担心这些,Composer会自动下载你需要的一切,一切都在composer.json的定义中。Composer对用户来说是非常透明的,但是背后的思想还是要明白,它的诞生并不是偶然的。得益于Github的快速发展,PHP语言越来越现代化,显得更加高大上。要想理解Composer,首先要了解它的结构:Composer的结构Composer命令行工具:这个理解比较简单。通过用户定义的Composer.json下载你需要的代码。如果你只是简单地使用Composer,那么你可以掌握一些特定的命令。自动加载代码加载器:通过Composer,开发者可以有多种使用方式,关键在于PHP的命名空间概念和PSR-4标准的制定。Composer刚刚基于这两者开发了一个代码自动加载器Github:有了Github,PHP开发者可以在上面托管开源代码,而Composer的开发起源于Github。Composer本质上是将Github上的代码下载到本地。Packagist:对于用户来说,使用的是Composer的命令行工具,那么命令行工具如何知道用户可以使用多少个包呢?这主要取决于Packagist。Packagist是Composer的主要包信息仓库。包开发者将具体代码托管在Github上,并将包信息提交给Packagist,以便用户可以通过Composer使用它。Composer根据本地定义的composer.json信息查询Packagist,Packagist使用Composer.json/Package.json信息的解析最终对应到github仓库。Composer最终下载代码的时候,也是依赖于Github仓库上的Composer.json。涉及到三种类型的composer.json,含义也不同。Composer.json:这是Composer的核心,也是Composer的规则。上面也提到了Composer.json的三种类型。使用时一定要注意区分。当我是初学者时,我总是搞砸了。Composer命令行工具composerinituser可以在自己的项目下创建composer.json来定义项目的依赖,也可以通过composerinit交互创建composer.json。composerinstall应该是最常用的命令,composer会根据本地的composer.json安装包,将下载的包放到项目下的vendor目录下,安装时的包版本信息放入composer.lock进行锁定版本。其实在安装的时候,如果发现composer.lock的版本和当前vendor目录下代码的版本相同的话,Composer是不会做任何事情的。composer.lock的目的是让你在当前版本中工作,而无需获取最新版本的包。Composerupdate那么如何更新composer.lock以便获取最新版本的包呢?此命令可用于更新包作曲家配置的最新版本。建议理解全局配置存放在COMPOSER_HOME/config.json,非全局配置信息存放在命令.composerconfig--list-gcomposerconfig-gnotify-on-installfalsecomposerglobalconfigbin-dir--absolutecomposercreate-这个项目目录下的project不常用,但是个人觉得还是很重要的。使用普通的install命令就是安装项目的所有依赖包下载到本项目的vendor目录下。通过这个命令,所有的代码和它的依赖包都放在一个目录下,相当于执行了一个gitclone命令。通常,包的开发者可能会用它来修复错误命令.composerglobal这是一个全局安装命令,可以让你在COMPOSER_HOME目录下执行Composer命令,比如install,update。当然,你的COMPOSER_HOME必须在$PATH环境中。比如执行composerglobalrequirefabpot/php-cs-fixer,现在可以全局运行php-cs-fixer命令行了。如果以后要更新,只需要运行composerglobalupdatecomposerdump-autoload。修改项目下的composer.json文件时,不需要运行composerupdate命令。更新,有时你可以使用这个命令来更新加载器。比如你要引用本地的自定义包(不是packagist的),这个命令后面会通过实践来讲解。composerrequire如果你手动或交互式创建composer.json文件,你可以直接使用这个命令安装包composerrequirecerdic/css-tidy:1.5.2composerrequire"ywdblog/phpcomposer:dev-master"--prefer-sourceand--prefer-dist参数--prefer-dist:对于稳定的包,一般Composer安装默认使用这个参数,这样也可以加快安装速度。例如,可以直接从packagist安装相应的包,而无需实际从Github下载包。--prefer-source:如果使用该参数,则直接从Github安装后,vendor目录也包含.git信息composerrequire"ywdblog/phpcomposer:dev-master"--prefer-source#包含.git信息在vendor/ywdblog/phpcomposer目录下用Composer下载特别慢,可以通过两种方式加速:composerconfigrepo.packagistcomposer“https://packagist.phpcomposer.com”编辑composer.json"repositories":{"packagist":{"type":"composer","url":"https://packagist.phpcomposer.com"}}自动加载代码composer本身集成了自动加载器,支持PSR-4,PSR-0,classmap,文件自动加载。下面举例说明如何使用Composer引用符合PSR-4标准的classmap、文件和本地代码。编辑composer.json"autoload":{"classmap":["othsrc/","classsrc.php"],"files":["othsrc/filesrc.php"],"psr-4":{"Foo\Bar\":"src"}}composerdump-autoloadviatheabove对于PSR-4,它相当于注册一个PSR-4autoloader(来自FooBar命名空间)。如果你不想使用Composer的自动加载器,你可以直接包含vendor/composer/autoload_*.php文件来配置你自己的加载器。具体例子托管在github上,大家可以参考。Repositories关于Repositories,不一定要懂,但是如果掌握了,就能更好的理解Composer。对于Repositories,它的中英文文档都有很好的解释,这里也做了一些摘录。包的基本概念:Composer是一个依赖管理工具。它会在本地安装一些资源包和包说明(如包名和对应的版本)。比较重要的元数据描述是dist和source,dist指向一个archive。archive是某个版本的资源包的打包。source指向一个正在开发的源,通常是一个源代码仓库(比如git)资源库:资源库是一个包的来源。这是一个包年龄/版本列表。Composer会查看你定义的所有repositories,以找到项目需要的资源包(这句话很重要)。Packagist.org默认已经注册了Composer(或者理解为Packagist.org是一个Composer资源库默认仓库类型)Composer资源库类型Composer资源库包括四种类型,默认是composer类型,也就是使用的资源类型通过packagist.org。它使用包含所有资源包元数据的单个packages.json文件。当你在pckagist.org上发布包时,默认系统会创建一个packages.json,但我并没有找到我的包对应的文件。VCS资源库类型如果你想构建一个私有的Composer私有资源库类型,你可以使用这个类型。这是一个例子。比如你自己的项目的composer.json定义如下,你可以使用Github上对应的代码。{"repositories":[{"type":"vcs","url":"https://github.com/ywdblog/phpcomposer"}],"require":{"ywdblog/phpcomposer":"dev-master"}}在运行composerupdate时,Comoser实际上包是从Github下载的,而不是pckagist.org。另外,如果需要使用Package资源库类型或者PEAR资源库类型,可以参考官方文档。通常,您可以在composer.json中定义name和version属性。Composer.json在本文中也多次提到了composer.json。比如你要使用第三方包,你需要在本地定义composer.json。Composer安装第三方包后,也会在第三方包目录下找到composer.json。那么这两个叫做composer.json有什么区别呢?理解这一点非常重要。如果在自己的项目下定义一个composer.json,这个包就叫做ROOT包,这个composer.json定义项目所需的条件(例如,您的项目可能依赖于第三方包)。composer.json中的一些属性只能在ROOT包中使用,比如config属性只在ROOT包中生效。一个资源包是否是ROOT包,取决于它的上下文,比如你gitcloneywdblog/phpcomposer,那么此时本地的phpcomposer目录就是ROOT包,如果你composerrequire本地phpcomposer目录下的ywdblog/phpcomposer,那么此时你的项目phpcomposer就是ROOT包。了解composer-schema.json可以参考这个网址。作为一个成熟的框架,Laravel对composer.json的定义非常经典。关于包的版本,用户在本地配置composer.json时,可以指定需要的包的具体版本,Composer是支持的。从Github仓库下载分支下的tag或package。对于Github上的Tag,Packagist会创建一个版本对应的package,符合X.Y.Z,vX.Y.Z,X.Y.Z-package类型,也就是说虽然Github上的package只有一个特定的版本,但是Composer支持多种形式的引用,如:composerrequiremonolog/monolog1.0.0-RC1composerrequiremonolog/monologv1.0.0-RC1composerrequiremonolog/monolog1.0.*composerrequiremonolog/monolog~1.10对于Github上的分支,Packagist会创建对应版本的包,如果分支名称看起来像一个版本,它会创建一个包版本号为{branchname}-dev,如果分支名称看起来不像一个版本号,它会创建一个包版本为dev-{branchname}版本号composerrequiremonolog/monologmaster-devcomposerrequiremonolog/monologmaster.x-dev总结:要理解Composer,最重要的是实践,***也可以理解PSR-4和命名空间,也可以尝试转换哟你的项目发布在pckagist.org上。
