Composer资源库

概述php

在此以前,咱们看到存在不一样类型的资源库,咱们须要了解一些基本概念,以理解 Composer 是如何构建于其上的。git

github

Composer 是一个依赖管理工具。它在本地安装一些资源包。一个包本质上就是一个包含东西的目录。一般状况下它存储 PHP 代码,但在理论上它能够是任何东西。而且它包含一个描述,其中有一个名称和一个版本号,这个名称和版本号用于识别该包。算法

事实上,在 composer 内部将每个版本都视为一个单独的包。尽管在你使用 composer 时这种区别可有可无,但当你想改变它时,这就显得相当重要。apache

除了名称和版本号,还存放了有用的元数据。与安装关系最密切的是 source 信息,它申明了在哪里能够得到资源包的内容。包数据指向包内容,并有两种指向方式:dist 和 source。json

Dist: dist 指向一个存档,该存档是对一个资源包的某个版本的数据进行的打包。一般是已经发行的稳定版本。缓存

Source: source 指向一个开发中的源。这一般是一个源代码仓库,例如 git。当你想要对下载下来的资源包进行修改时,能够这样获取。服务器

你可使用其中任意一个,或者同时使用。这取决于其它的一些因素,好比“user-supplied 选项”和“包的稳定性”,前者将会被优先考虑。架构

资源库composer

一个资源库是一个包的来源。它是一个 packages/versions 的列表。Composer 将查看全部你定义的 repositories 以找到你项目须要的资源包。

默认状况下已经将 Packagist.org 注册到 Composer。你能够在 composer.json 中申明更多的资源库,把它们加入你的项目中。

资源库的定义仅可用于“root 包”,而在你依赖的包中定义的资源库将不会被加载。若是你想了解其中的缘由,请阅读 FAQ entry。

Types

Composer

主资源库的类型为 composer。它使用一个单一的 packages.json 文件,包含了全部的资源包元数据。

这也是 packagist.org 所使用的资源类型。要引用一个 composer 资源库,只须要提供一个存放 packages.json 文件的 目录路径。好比要引用 packagist.org 下的 /packages.json,它的 URL 就应该是 packagist.org。而 example.org/packages.json 的 URL 应该是 example.org。

packages

惟一必须的字段是 packages。它的 JSON 结构以下:

{
    "packages": {
        "vendor/package-name": {
            "dev-master": { @composer.json },
            "1.0.x-dev": { @composer.json },
            "0.0.1": { @composer.json },
            "1.0.0": { @composer.json }
        }
    }
}

@composer.json 标记将会今后包的指定版本中读取 composer.json 的内容,其内至少应包含如下信息:

name
version
dist or source

这是一个最简单的包定义:

{
    "name": "smarty/smarty",
    "version": "3.1.7",
    "dist": {
        "url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
        "type": "zip"
    }
}

它还能够包含任何在 composer.json 架构 中介绍的字段。

notify-batch

notify-batch 字段容许你指定一个 URL,它将会在用户安装每个包时被调用。该 URL 能够是(与其资源库相同域名的)绝对路径或者一个完整的 URL 地址。

例如使用下面的值:

{
    "notify-batch": "/downloads/"
}

对于 example.org/packages.json 包含的 monolog/monolog 包,它将会发送一个 POST 请求到 example.org/downloads/,使用下面的 JSON request body:

{
    "downloads": [
        {"name": "monolog/monolog", "version": "1.2.1.0"},
    ]
}

version 字段将包含标准化的版本号。

notify-batch 字段是可选的。

includes

对于较大的资源库,能够拆分 packages.json 为多个文件。includes 字段容许你引用这些额外的文件。

例:

{
    "includes": {
        "packages-2011.json": {
            "sha1": "525a85fb37edd1ad71040d429928c2c0edec9d17"
        },
        "packages-2012-01.json": {
            "sha1": "897cde726f8a3918faf27c803b336da223d400dd"
        },
        "packages-2012-02.json": {
            "sha1": "26f911ad717da26bbcac3f8f435280d13917efa5"
        }
    }
}

文件的 SHA-1 码容许它被缓存,仅在 hash 值改变时从新请求。

此字段是可选的。你也许并不须要它来自定义存储库。

provider-includes and providers-url

的对于很是大的资源库,像 packagist.org 使用 so-called provider 文件是首选方法。provider-includes 字段容许你设置一个列表,来申明这个资源库提供的包名称。在这种状况下文件的哈希算法必须使用 sha256。

providers-url 描述了如何在服务器上找到这些 provider 文件。它是以资源库的根目录为起点的绝对路径。

例:

{
    "provider-includes": {
        "providers-a.json": {
            "sha256": "f5b4bc0b354108ef08614e569c1ed01a2782e67641744864a74e788982886f4c"
        },
        "providers-b.json": {
            "sha256": "b38372163fac0573053536f5b8ef11b86f804ea8b016d239e706191203f6efac"
        }
    },
    "providers-url": "/p/%package%$%hash%.json"
}

这些文件包含资源包的名称以及哈希值,以验证文件的完整性,例如:

{
    "providers": {
        "acme/foo": {
            "sha256": "38968de1305c2e17f4de33aea164515bc787c42c7e2d6e25948539a14268bb82"
        },
        "acme/bar": {
            "sha256": "4dd24c930bd6e1103251306d6336ac813b563a220d9ca14f4743c032fb047233"
        }
    }
}

上述文件申明了 acme/foo 和 acme/bar 能够在这个资源库找到,经过加载由 providers-url 引用的文件,替换 %name% 为包名而且替换 %hash% 为 sha256 的值。这些文件自己只包含上文提到的 packages 的定义。

这些字段是可选的。你也许并不须要它们来自定义存储库。

stream options

packages.json 文件是用一个 PHP 流加载的。你可使用 options 参数来设定额外的流信息。你能够设置任何有效的PHP 流上下文选项。更多相关信息请查看 Context options and parameters。

VCS

VCS 表示版本控制系统。这包括像 git、svn 或 hg 这样的版本管理系统。Composer 有一个资源类型能够从这些系统安装软件包。

从 VCS 资源库加载一个包

这里有几个用例。最多见的是维护本身 fork 的第三方库。若是你在项目中使用某些库,而且你决定改变这些库内的某些东西,你会但愿你项目中使用的是你本身的修正版本。若是这个库是在 GitHub 上(这种状况常常出现),你能够简单的 fork 它并 push 你的变动到这个 fork 里。在这以后你更新项目的 composer.json 文件,添加你的 fork 做为一个资源库,变动版本约束来指向你的自定义分支。关于版本约束的命名约定请查看 库(资源包)。

例如,假设你 fork 了 monolog,在 bugfix 分支修复了一个 bug:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/igorw/monolog"
        }
    ],
    "require": {
        "monolog/monolog": "dev-bugfix"
    }
}

当你运行 php composer.phar update 时,你应该获得你修改的版本,而不是 packagist.org 上的 monolog/monolog。

注意,你不该该对包进行重命名,除非你真的打算摆脱原来的包,并长期的使用你本身的 fork。这样 Composer 就会正确获取你的包了。若是你肯定要重命名这个包,你应该在默认分支(一般是 master 分支)上操做,而不是特性分支,由于包的名字取自默认分支。

若是其它包依赖你 fork 的这个分支,可能要对它作版本号的行内别名设置,才可以准确的识别版本约束。更多相关信息请查看 别名。

使用私有资源库

彻底相同的解决方案,也可让你使用你 GitHub 和 BitBucket 上的私人代码库进行工做:

{
    "require": {
        "vendor/my-private-repo": "dev-master"
    },
    "repositories": [
        {
            "type": "vcs",
            "url":  "git@bitbucket.org:vendor/my-private-repo.git"
        }
    ]
}

惟一的要求是为一个 git 客户端安装 SSH 秘钥。

Git 的备选方案

Git 并非 VCS 资源库惟一支持的版本管理系统。

如下几种都是被支持的:

Git: git-scm.com
Subversion: subversion.apache.org
Mercurial: mercurial.selenic.com

为了从这些系统获取资源包,你必须安装对应的客户端,这多是不方便的。基于这个缘由,这里提供了 GitHub 和 BitBucket 的 API 的特殊支持,以便在无需安装版本控制系统的状况下获取资源包。在 VCS 资源库提供的 dist 中获取 zip 存档。

GitHub: github.com (Git)
BitBucket: bitbucket.org (Git and Mercurial)

VCS 驱动将基于 URL 自动检测版本库类型。但若是可能,你须要明确的指定一个 git、svn 或 hg 做为资源库类型,而不是 vcs。

Subversion 选项

因为 Subversion 没有原生的分支和标签的概念,Composer 假设在默认状况下该代码位于 $url/trunk、$url/branches 和 $url/tags 内。若是你的存储库使用了不一样的布局,你能够更改这些值。例如,若是你使用大写的名称,你能够像这样配置资源库:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "http://svn.example.org/projectA/",
            "trunk-path": "Trunk",
            "branches-path": "Branches",
            "tags-path": "Tags"
        }
    ]
}

若是你的存储库目录中没有任何分支或标签文件夹,你能够将 branches-path 或 tags-path 设置为 false。

若是是一个位于子目录的包,例如, /trunk/foo/bar/composer.json 和 /tags/1.0/foo/bar/composer.json,那么你可让 composer 经过 "package-path" 选项设置的子目录进行访问,在这个例子中能够将其设置为 "package-path": "foo/bar/"。

PEAR

pear 类型资源库,使得从任何 PEAR 渠道安装资源包成为可能。Composer 将为全部此类型的包增长前缀(相似于 pear-{渠道名称}/)以免冲突。而在以后使用别名时也增长前缀(如 pear-{渠作别名}/)。

例如使用 pear2.php.net:

{
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear2.php.net"
        }
    ],
    "require": {
        "pear-pear2.php.net/PEAR2_Text_Markdown": "*",
        "pear-pear2/PEAR2_HTTP_Request": "*"
    }
}

在这种状况下渠道的简称(别名)是 pear2,所以 PEAR2_HTTP_Request 包的名称应该写做 pear-pear2/PEAR2_HTTP_Request。

注意: pear 类型的资源库对每一个 requires 都要作完整的请求,所以可能大大下降安装速度。

自定义供应商别名

经过自定义供应商名称,对 PEAR 渠道包进行别名是容许的。

例:

假设你有一个私人 PEAR 库,并但愿使用 Composer 从 VCS 集成依赖。你的 PEAR 库包含如下资源包:

BasePackage。
IntermediatePackage 依赖于 BasePackage。
TopLevelPackage1 和 TopLevelPackage2 都依赖于 IntermediatePackage。

若是没有一个供应商别名,Composer 将使用 PEAR 渠道名称做为包名的一部分:

pear-pear.foobar.repo/BasePackage
pear-pear.foobar.repo/IntermediatePackage
pear-pear.foobar.repo/TopLevelPackage1
pear-pear.foobar.repo/TopLevelPackage2

假设以后的某个时间,你但愿将你的 PEAR 包迁移,使用 Composer 资源库和命名方案,而且采用 foobar 做为供应商名称。这样以前使用 PEAR 包的项目将不会看到更新的资源包,由于它们有不一样的供应商名称(foobar/IntermediatePackage 与 pear-pear.foobar.repo/IntermediatePackage)。

你能够经过从一开始就为 PEAR 资源库指定 vendor-alias 来避免这种状况的发生,以获得一个不会过期的包名。

为了说明这一点,下面的例子会从你的 PEAR 资源库中获得 BasePackage、TopLevelPackage1 和 TopLevelPackage2 资源包,并从 Github 资源库中获取 IntermediatePackage 资源包:

{
    "repositories": [
        {
            "type": "git",
            "url": "https://github.com/foobar/intermediate.git"
        },
        {
            "type": "pear",
            "url": "http://pear.foobar.repo",
            "vendor-alias": "foobar"
        }
    ],
    "require": {
        "foobar/TopLevelPackage1": "*",
        "foobar/TopLevelPackage2": "*"
    }
}

Package

若是你想使用一个项目,它没法经过上述任何一种方式支持 composer,你仍然可使用 package 类型定义资源库。

基本上,你能够定义与 packages.json 中 composer 类型资源库相同的信息,但须要为每一个这样的资源包分别定义。一样,至少应该包含如下信息:name、version、(dist 或 source)。

这是一个 smarty 模板引擎的例子:

{
    "repositories": [
        {
            "type": "package",
            "package": {
                "name": "smarty/smarty",
                "version": "3.1.7",
                "dist": {
                    "url": "http://www.smarty.net/files/Smarty-3.1.7.zip",
                    "type": "zip"
                },
                "source": {
                    "url": "http://smarty-php.googlecode.com/svn/",
                    "type": "svn",
                    "reference": "tags/Smarty_3_1_7/distribution/"
                },
                "autoload": {
                    "classmap": ["libs/"]
                }
            }
        }
    ],
    "require": {
        "smarty/smarty": "3.1.*"
    }
}

一般你不须要去定义 source,由于你并非真的须要它。

注意: 该资源库类型存在如下限制,所以应尽量避免使用:

    Composer 将不会更新资源包,除非你修改了 version 字段。
    Composer 将不会更新 commit references,所以若是你使用 master reference,将不得不删除该程序包以强制更新,而且将不得不面对一个不稳定的 lock 文件。

Hosting your own

尽管大部分的时间,你大概都会把资源包放在 packagist.org 上,但这里还将告诉你一些用例,以便你能够自行托管资源库。

Private company packages: 若是你是一个公司的职员,对公司内部的资源包使用 composer,你可能会想让这些包保持私有的状态。

Separate ecosystem: 若是你的项目有本身的生态系统,而且本身的资源包不须要被其它项目所复用,你可能会想将它们从 packagist.org 上分离出来。其中一个例子就是 wordpress 的插件。

对于自行托管的软件包,建议使用 composer 类型资源库设置,它将提供最佳的性能。

这里有一些工具,能够帮助你建立 composer 类型的资源库。

Packagist

packagist 的底层是开源的。这意味着你能够只安装你本身拷贝的 packagist,改造并使用它。这真的是很直接简单的事情。然而,因为其规模和复杂性,对于大多数中小型企业仍是建议使用 Satis。

Packagist 是一个 Symfony2 应用程序,而且托管在 GitHub 上 github.com/composer/packagist。它内部使用了 composer 并做为 VCS 资源库与 composer 用户之间的代理。它拥有全部 VCS 资源包的列表,按期从新抓取它们,并将其做为一个 composer 资源库。

要设置你的副本,只须要按照 github.com/composer/packagist 的说明进行操做。

Satis

Satis 是一个静态的 composer 资源库生成器。它像是一个超轻量级的、基于静态文件的 packagist 版本。

你给它一个包含 composer.json 的存储库,定义好 VCS 和 资源库。它会获取全部你列出的包,并打印 packages.json 文件,做为 composer 类型的资源库。

更多详细信息请查看 github.com/composer/satis 和 Satis article。

Artifact

在某些状况下,或许没有能力拥有以前提到的任何一种线上资源库。Typical example could be cross-organisation library exchange through built artifacts。固然大部分的时间他们都是私有的。为了简化维护,能够简单的使用 artifact 资源库类型,来引用一个包含那些私有包的 ZIP 存档的文件夹:

{
    "repositories": [
        {
            "type": "artifact",
            "url": "path/to/directory/with/zips/"
        }
    ],
    "require": {
        "private-vendor-one/core": "15.6.2",
        "private-vendor-two/connectivity": "*",
        "acme-corp/parser": "10.3.5"
    }
}

每一个 zip artifact 都只是一个 ZIP 存档,放置在 composer.json 所在的根目录:

$ unzip -l acme-corp-parser-10.3.5.zip
composer.json
...

若是有两个不一样版本的资源包,它们都会被导入。当有一个新版本的存档被添加到 artifact 文件夹,而且你运行了 update 命令,该版本就会被导入,而且 Composer 将更新到最新版本。

禁用 Packagist

你能够在 composer.json 中禁用默认的 Packagist 资源库。

{
    "repositories": [
        {
            "packagist": false
        }
    ]
}
相关文章
相关标签/搜索