Composer 資源庫

2018-09-28 20:23 更新

資源庫

本章將解釋包和庫的概念,什么樣的存儲庫是可用的,以及它們?nèi)绾喂ぷ鳌?/p>

概述

在此之前,我們看到存在不同類型的資源庫,我們需要了解一些基本概念,以理解 Composer 是如何構(gòu)建于其上的。

Composer 是一個依賴管理工具。它在本地安裝一些資源包。一個包本質(zhì)上就是一個包含東西的目錄。通常情況下它存儲 PHP 代碼,但在理論上它可以是任何東西。并且它包含一個描述,其中有一個名稱和一個版本號,這個名稱和版本號用于識別該包。

事實上,在 composer 內(nèi)部將每一個版本都視為一個單獨的包。盡管在你使用 composer 時這種區(qū)別無關(guān)緊要,但當(dāng)你想改變它時,這就顯得至關(guān)重要。

除了名稱和版本號,還存放了有用的元數(shù)據(jù)。與安裝關(guān)系最密切的是 source 信息,它申明了在哪里可以獲得資源包的內(nèi)容。包數(shù)據(jù)指向包內(nèi)容,并有兩種指向方式:dist 和 source。

Dist: dist 指向一個存檔,該存檔是對一個資源包的某個版本的數(shù)據(jù)進(jìn)行的打包。通常是已經(jīng)發(fā)行的穩(wěn)定版本。

Source: source 指向一個開發(fā)中的源。這通常是一個源代碼倉庫,例如 git。當(dāng)你想要對下載下來的資源包進(jìn)行修改時,可以這樣獲取。

你可以使用其中任意一個,或者同時使用。這取決于其它的一些因素,比如“user-supplied 選項”和“包的穩(wěn)定性”,前者將會被優(yōu)先考慮。

資源庫

一個資源庫是一個包的來源。它是一個 packages/versions 的列表。Composer 將查看所有你定義的 repositories 以找到你項目需要的資源包。

默認(rèn)情況下已經(jīng)將 Packagist.org 注冊到 Composer。你可以在 composer.json 中申明更多的資源庫,把它們加入你的項目中。

資源庫的定義僅可用于“root 包”,而在你依賴的包中定義的資源庫將不會被加載。如果你想了解其中的原因,請閱讀 FAQ entry。

Types

Composer

主資源庫的類型為 composer。它使用一個單一的 packages.json 文件,包含了所有的資源包元數(shù)據(jù)。

這也是 packagist.org 所使用的資源類型。要引用一個 composer 資源庫,只需要提供一個存放 packages.json 文件的 目錄路徑。比如要引用 packagist.org 下的 /packages.json,它的 URL 就應(yīng)該是 packagist.org。而 example.org/packages.json 的 URL 應(yīng)該是 example.org。

packages

唯一必須的字段是 packages。它的 JSON 結(jié)構(gòu)如下:

{
    "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 標(biāo)記將會從此包的指定版本中讀取 composer.json 的內(nèi)容,其內(nèi)至少應(yīng)包含以下信息:

  • 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 架構(gòu) 中介紹的字段。

notify-batch

notify-batch 字段允許你指定一個 URL,它將會在用戶安裝每一個包時被調(diào)用。該 URL 可以是(與其資源庫相同域名的)絕對路徑或者一個完整的 URL 地址。

例如使用下面的值:

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

對于 example.org/packages.json 包含的 monolog/monolog 包,它將會發(fā)送一個 POST 請求到 example.org/downloads/,使用下面的 JSON request body:

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

version 字段將包含標(biāo)準(zhǔn)化的版本號。

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 字段允許你設(shè)置一個列表,來申明這個資源庫提供的包名稱。在這種情況下文件的哈希算法必須使用 sha256。

providers-url 描述了如何在服務(wù)器上找到這些 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/fooacme/bar 可以在這個資源庫找到,通過加載由 providers-url 引用的文件,替換 %package% 為包名并且替換 %hash% 為 sha256 的值。這些文件本身只包含上文提到的 packages 的定義。

這些字段是可選的。你也許并不需要它們來自定義存儲庫。

stream options

packages.json 文件是用一個 PHP 流加載的。你可以使用 options 參數(shù)來設(shè)定額外的流信息。你可以設(shè)置任何有效的PHP 流上下文選項。更多相關(guān)信息請查看 Context options and parameters。

VCS

VCS 表示版本控制系統(tǒng)。這包括像 git、svn 或 hg 這樣的版本管理系統(tǒng)。Composer 有一個資源類型可以從這些系統(tǒng)安裝軟件包。

從 VCS 資源庫加載一個包

這里有幾個用例。最常見的是維護(hù)自己 fork 的第三方庫。如果你在項目中使用某些庫,并且你決定改變這些庫內(nèi)的某些東西,你會希望你項目中使用的是你自己的修正版本。如果這個庫是在 GitHub 上(這種情況經(jīng)常出現(xiàn)),你可以簡單的 fork 它并 push 你的變更到這個 fork 里。在這之后你更新項目的 composer.json 文件,添加你的 fork 作為一個資源庫,變更版本約束來指向你的自定義分支。關(guān)于版本約束的命名約定請查看 庫(資源包)。

例如,假設(shè)你 fork 了 monolog,在 bugfix 分支修復(fù)了一個 bug:

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

當(dāng)你運行 php composer.phar update 時,你應(yīng)該得到你修改的版本,而不是 packagist.org 上的 monolog/monolog。

注意,你不應(yīng)該對包進(jìn)行重命名,除非你真的打算擺脫原來的包,并長期的使用你自己的 fork。這樣 Composer 就會正確獲取你的包了。如果你確定要重命名這個包,你應(yīng)該在默認(rèn)分支(通常是 master 分支)上操作,而不是特性分支,因為包的名字取自默認(rèn)分支。

如果其它包依賴你 fork 的這個分支,可能要對它做版本號的行內(nèi)別名設(shè)置,才能夠準(zhǔn)確的識別版本約束。更多相關(guān)信息請查看 別名。

使用私有資源庫

完全相同的解決方案,也可以讓你使用你 GitHub 和 BitBucket 上的私人代碼庫進(jìn)行工作:

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

唯一的要求是為一個 git 客戶端安裝 SSH 秘鑰。

Git 的備選方案

Git 并不是 VCS 資源庫唯一支持的版本管理系統(tǒng)。

以下幾種都是被支持的:

為了從這些系統(tǒng)獲取資源包,你必須安裝對應(yīng)的客戶端,這可能是不方便的?;谶@個原因,這里提供了 GitHub 和 BitBucket 的 API 的特殊支持,以便在無需安裝版本控制系統(tǒng)的情況下獲取資源包。在 VCS 資源庫提供的 dist 中獲取 zip 存檔。

VCS 驅(qū)動將基于 URL 自動檢測版本庫類型。但如果可能,你需要明確的指定一個 gitsvnhg 作為資源庫類型,而不是 vcs。

If you set the no-api key to true on a github repository it will clone the repository as it would with any other git repository instead of using the GitHub API. But unlike using the git driver directly, composer will still attempt to use github's zip files.

Subversion 選項

由于 Subversion 沒有原生的分支和標(biāo)簽的概念,Composer 假設(shè)在默認(rèn)情況下該代碼位于 $url/trunk、$url/branches$url/tags 內(nèi)。如果你的存儲庫使用了不同的布局,你可以更改這些值。例如,如果你使用大寫的名稱,你可以像這樣配置資源庫:

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

如果你的存儲庫目錄中沒有任何分支或標(biāo)簽文件夾,你可以將 branches-pathtags-path 設(shè)置為 false。

如果是一個位于子目錄的包,例如, /trunk/foo/bar/composer.json/tags/1.0/foo/bar/composer.json,那么你可以讓 composer 通過 "package-path" 選項設(shè)置的子目錄進(jìn)行訪問,在這個例子中可以將其設(shè)置為 "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 包的名稱應(yīng)該寫作 pear-pear2/PEAR2_HTTP_Request

注意: pear 類型的資源庫對每個 requires 都要做完整的請求,因此可能大大降低安裝速度。

自定義供應(yīng)商別名

通過自定義供應(yīng)商名稱,對 PEAR 渠道包進(jìn)行別名是允許的。

例:

假設(shè)你有一個私人 PEAR 庫,并希望使用 Composer 從 VCS 集成依賴。你的 PEAR 庫包含以下資源包:

  • BasePackage。
  • IntermediatePackage 依賴于 BasePackage
  • TopLevelPackage1TopLevelPackage2 都依賴于 IntermediatePackage。

如果沒有一個供應(yīng)商別名,Composer 將使用 PEAR 渠道名稱作為包名的一部分:

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

假設(shè)之后的某個時間,你希望將你的 PEAR 包遷移,使用 Composer 資源庫和命名方案,并且采用 foobar 作為供應(yīng)商名稱。這樣之前使用 PEAR 包的項目將不會看到更新的資源包,因為它們有不同的供應(yīng)商名稱(foobar/IntermediatePackagepear-pear.foobar.repo/IntermediatePackage)。

你可以通過從一開始就為 PEAR 資源庫指定 vendor-alias 來避免這種情況的發(fā)生,以得到一個不會過時的包名。

為了說明這一點,下面的例子會從你的 PEAR 資源庫中得到 BasePackageTopLevelPackage1TopLevelPackage2 資源包,并從 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.jsoncomposer 類型資源庫相同的信息,但需要為每個這樣的資源包分別定義。同樣,至少應(yīng)該包含以下信息:name、version、(distsource)。

這是一個 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,因為你并不是真的需要它。

注意: 該資源庫類型存在以下限制,因此應(yīng)盡可能避免使用:

  • Composer 將不會更新資源包,除非你修改了 version 字段。
  • Composer 將不會更新 commit references,因此如果你使用 master reference,將不得不刪除該程序包以強(qiáng)制更新,并且將不得不面對一個不穩(wěn)定的 lock 文件。

Hosting your own

盡管大部分的時間,你大概都會把資源包放在 packagist.org 上,但這里還將告訴你一些用例,以便你可以自行托管資源庫。

  • Private company packages: 如果你是一個公司的職員,對公司內(nèi)部的資源包使用 composer,你可能會想讓這些包保持私有的狀態(tài)。

  • Separate ecosystem: 如果你的項目有自己的生態(tài)系統(tǒng),并且自己的資源包不需要被其它項目所復(fù)用,你可能會想將它們從 packagist.org 上分離出來。其中一個例子就是 wordpress 的插件。

對于自行托管的軟件包,建議使用 composer 類型資源庫設(shè)置,它將提供最佳的性能。

這里有一些工具,可以幫助你創(chuàng)建 composer 類型的資源庫。

Packagist

packagist 的底層是開源的。這意味著你可以只安裝你自己拷貝的 packagist,改造并使用它。這真的是很直接簡單的事情。然而,由于其規(guī)模和復(fù)雜性,對于大多數(shù)中小型企業(yè)還是建議使用 Satis。

Packagist 是一個 Symfony2 應(yīng)用程序,并且托管在 GitHub 上 github.com/composer/packagist。它內(nèi)部使用了 composer 并作為 VCS 資源庫與 composer 用戶之間的代理。它擁有所有 VCS 資源包的列表,定期重新抓取它們,并將其作為一個 composer 資源庫。

要設(shè)置你的副本,只需要按照 github.com/composer/packagist 的說明進(jìn)行操作。

Satis

Satis 是一個靜態(tài)的 composer 資源庫生成器。它像是一個超輕量級的、基于靜態(tài)文件的 packagist 版本。

你給它一個包含 composer.json 的存儲庫,定義好 VCS 和 資源庫。它會獲取所有你列出的包,并打印 packages.json 文件,作為 composer 類型的資源庫。

更多詳細(xì)信息請查看 github.com/composer/satis 和 Satis article。

Artifact

在某些情況下,或許沒有能力擁有之前提到的任何一種線上資源庫。Typical example could be cross-organisation library exchange through built artifacts。當(dāng)然大部分的時間他們都是私有的。為了簡化維護(hù),可以簡單的使用 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
...

如果有兩個不同版本的資源包,它們都會被導(dǎo)入。當(dāng)有一個新版本的存檔被添加到 artifact 文件夾,并且你運行了 update 命令,該版本就會被導(dǎo)入,并且 Composer 將更新到最新版本。

禁用 Packagist

你可以在 composer.json 中禁用默認(rèn)的 Packagist 資源庫。

{
    "repositories": [
        {
            "packagist": false
        }
    ]
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號