儲存庫#
本章節將說明套件和儲存庫的概念,有哪些種類的儲存庫,以及它們如何運作。
概念#
在查看現有的不同類型儲存庫之前,我們需要了解 Composer 上的一些基本概念。
套件#
Composer 是一種依賴關係管理員。它會在本地安裝套件。一般來說,套件是包含某些內容的目錄。就本例而言是 PHP 程式碼,但理論上它可以是任何東西。套件中包含有名稱和版本的套件說明。名稱和版本會用來識別套件。
事實上,Composer 在內部將每個版本視為獨立的套件。使用 Composer 時,這種區別並不重要,但如果您要變更套件時,這將非常重要。
除了名稱和版本外,還有一些有用的中繼資料。與安裝最相關的資訊是來源定義,它描述了套件內容的取得位置。套件資料指向套件內容。這裡有兩個選項:dist 和 source。
Dist:Dist 是套件資料的封裝版本。通常是已發布的版本,也通常是穩定的版本。
Source:Source 用於開發。它通常來自原始碼儲存庫,例如 git。當您想要修改下載的套件時,您可以取得它。
套件可以提供其中任何一個,甚至都可以提供兩個選項。取決於特定因素,例如使用者提供的選項和套件穩定性,將會偏好某一個選項。
儲存庫#
儲存庫是封裝的來源,是一串封裝 / 版本的清單。Composer 會在所有儲存庫中尋找專案所需的封裝。
預設上只在 Composer 中註冊 Packagist.org 儲存庫。你可以透過在 composer.json
中宣告的方式,在專案中新增更多儲存庫。
儲存庫只能供根目錄的封裝使用,且你的依存焦點所定義的儲存庫將不會載入。如果您想知道原因,請參閱 常見問題文章。
解決依賴關係時,Composer 會自上而下尋找儲存庫中的封裝,而預設上會在一個封裝中找到一個符合的封裝後,就不會再繼續在其他儲存庫中尋找。請參閱 儲存庫優先順序 文章,以瞭解更多詳細資訊,並查看如何變更這種行為。
類型#
Composer#
主要的儲存庫類型是 composer
儲存庫,它使用一個包含所有封裝中繼資料的 packages.json
檔。
這也是 Packagist 使用的儲存庫類型。若要參考一個 composer
儲存庫,請在 packages.json
檔之前提供路徑。對於 Packagist,該檔位於 /packages.json
,因此儲存庫的網址應為 repo.packagist.org
。對於 example.org/packages.json
儲存庫網址應為 example.org
。
{
"repositories": [
{
"type": "composer",
"url": "https://example.org"
}
]
}
封裝#
唯一需要的欄位是 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": "smarty/smarty",
"version": "3.1.7",
"dist": {
"url": "https://www.smarty.net/files/Smarty-3.1.7.zip",
"type": "zip"
}
}
它可能包含 架構中指定的其他任何欄位。
notify-batch#
notify-batch
欄位讓你能夠指定一個 URL,在每次使用者安裝一個封裝時將會呼叫該 URL。該網址可以是絕對路徑(會使用相同網域作為儲存庫),或是一個完全限定的 URL。
一個範例值
{
"notify-batch": "/downloads/"
}
對於包含一個 monolog/monolog
封裝的 example.org/packages.json
會將一個 POST
要求傳送至 example.org/downloads/
其中有以下的 JSON 要求資訊
{
"downloads": [
{"name": "monolog/monolog", "version": "1.2.1.0"}
]
}
版本欄位會包含該版本號碼的標準表示形式。
此欄位是選填的。
metadata-url、available-packages 和 available-package-patterns#
metadata-url
欄位讓你能夠提供一個 URL 模板,用於提供儲存庫中所有封裝。它必須包含 %package%
佔位符。
此欄位是 Composer v2 的新功能,如果同時存在 provider-includes
和 providers-url
欄位,它會優先於這些欄位。為了同時相容於 Composer v1 和 v2,理想上你應同時提供這兩種欄位。然而,新的儲存庫實作可能只需要支援 v2。換句話說
範例
{
"metadata-url": "/p2/%package%.json"
}
當 Composer 在尋找 package 時,它將以 package 名稱取代 %package%
,並取得該 URL。如果允許該 package 的開發穩定性,它也會在 $packageName~dev
中再次載入 URL(例如 /p2/foo/bar~dev.json
來尋找 foo/bar
的開發版本)。
包含 package 版本的 foo/bar.json
和 foo/bar~dev.json
檔案只能包含 foo/bar
package 的版本,例如 {"packages":{"foo/bar":[ ... 版本在此 ... ]}}
。
快取是透過 If-Modified-Since 標頭來進行的,因此請確保您有傳回 Last-Modified 標頭,且其正確無誤。
version 陣列也可以選擇使用 composer/metadata-minifier 中的 Composer\MetadataMinifier\MetadataMinifier::minify()
來縮小。如果這樣做,您應該在最上層加入 "minified": "composer/2.0"
金鑰,以告知 Composer 它必須將版本清單展開回原始資料。請參閱 https://repo.packagist.org/p2/monolog/monolog.json 以取得範例。
任何不存在的請求的 package 都必須傳回 404 狀態碼,這將指示 Composer 此 package 在您的儲存庫中不存在。確保 404 回應快速,以避免阻擋 Composer。避免重新導向到其他 404 頁面。
如果您的儲存庫只有少數 package,而且您想要避免 404 請求,您也可以在 packages.json
中指定「 "available-packages"
」金鑰,它應該是一個包含儲存庫中所有 package 名稱的陣列。或者,您可以指定「 "available-package-patterns"
」金鑰,它是一個 package 名稱模式的陣列(使用 *
與任何字串相符,例如 vendor/*
會讓 Composer 檢視此儲存庫中每個相符的 package 名稱)。
此欄位是選填的。
providers-api#
providers-api
欄位允許您提供一個 URL 範本,用於服務所有提供給定 package 名稱的 package,但不包含具有該名稱的 package。它必須包含佔位符 %package%
。
例如 https://packagist.org/providers/monolog/monolog.json 列出一些具有 monolog/monolog「提供」規則的 package,但它本身並沒有列出 monolog/monolog。
{
"providers-api": "https://packagist.org/providers/%package%.json",
}
此欄位是選填的。
list#
list
欄位允許您傳回與給定篩選器相符的 package 名稱(如果沒有篩選器,則傳回所有名稱)。它應該接受一個 ?filter=xx
查詢參數,其中 *
可以作為萬用字元與任何子字串相符。
此處不應考慮替換/提供規則。
它必須傳回一個 package 名稱陣列
{
"packageNames": [
"a/b",
"c/d"
]
}
請參閱 https://packagist.org/packages/list.json?filter=composer/* 以取得範例。
此欄位是選填的。
provider-includes 和 providers-url#
provider-includes
欄位允許您列出列出這個儲存庫所提供的套件名稱的檔案。檔案的雜湊值應該是 sha256。
providers-url
描述伺服器上的提供者檔案是如何被找到的。它是儲存庫根目錄的絕對路徑。它必須包含佔位符 %package%
和 %hash%
。
這些欄位由 Composer v1 使用,或如果您的儲存庫沒有設定 metadata-url
欄位。
範例
{
"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
所參考的檔案,用提供者命名空間套件名稱取代 %package%
,以及用 sha256 欄位取代 %hash%
。這些檔案本身包含套件定義,如 上面 所述。
這些欄位是選配的。您可能不需要它們來使用您自己的自訂儲存庫。
cURL 或串流選項#
儲存庫的存取方式是使用 cURL(已啟用 ext-curl 的 Composer 2)或 PHP 串流。您可以使用 options
參數設定額外的選項。對於 PHP 串流,您可以設定任何有效的 PHP 串流環境設定選項。請參閱 環境設定選項和參數 以取得更多資訊。當使用 cURL 時,只能設定一組有限的 http
和 ssl
選項。
{
"repositories": [
{
"type": "composer",
"url": "https://example.org",
"options": {
"http": {
"timeout": 60
}
}
}
],
"require": {
"acme/package": "^1.0"
}
}
VCS#
VCS 代表版本控制系統。這包括像是 git、svn、fossil 或 hg 等的版本控制系統。Composer 有適用於從這些系統安裝套件的儲存庫類型。
從 VCS 儲存庫載入套件#
有幾個使用案例適用於這個。最常見的是維護您自己的協力廠商程式庫分支。如果您正在為您的專案使用特定的程式庫,並且您決定變更程式庫中的某些內容,您會希望您的專案使用已修補的版本。如果程式庫在 GitHub 上(在大部分情況下都是如此),您可以在那裡分岔並將您的變更推送到您的分岔。然後更新專案的 composer.json
。您所要做的就是新增您的分岔為儲存庫,並更新版本約束以指向您的自訂分支。只有在 composer.json
中,您應該在您的自訂分支名稱前面加上 "dev-"
(不要使它成為實際分支名稱的一部分)。有關版本約束命名慣例,請參閱 程式庫 以取得更多資訊。
假設您修補了 monolog 以修正 bugfix
分支中的錯誤
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/igorw/monolog"
}
],
"require": {
"monolog/monolog": "dev-bugfix"
}
}
當您執行 php composer.phar update
時,您應該取得您修改過的 monolog/monolog
版本,而不是來自 packagist 的版本。
請注意,不要重新命名套件,除非你真的有意長期發展分岔,並且完全從原來的套件移開。因為自訂儲存庫優先於 packagist,所以 Composer 會正確地選擇你的套件,而不是原來的套件。如果你想重新命名套件,你應在預設(通常為 master)分支而不是功能分支中執行,因為套件名稱取自預設分支。
另外請注意,如果你在已分岔儲存庫的 `composer.json` 檔案中變更 `name` 屬性,覆寫將無法運作,因為覆寫才能運作的條件是它必須與原來的屬性相符。
如果其他依賴項依賴於你已分岔的套件,你可以將其別名化,以便它符合它否則無法符合的限制。如需更多資訊,請參閱別名這篇文章。
使用私人儲存庫#
完全相同的解決方案讓你能夠在 GitHub 和 Bitbucket 中使用你的私人儲存庫
{
"repositories": [
{
"type": "vcs",
"url": "git@bitbucket.org:vendor/my-private-repo.git"
}
],
"require": {
"vendor/my-private-repo": "dev-master"
}
}
唯一的條件是為 git 客戶端安裝 SSH 金鑰。
Git 替代方案#
Git 並不是 VCS 儲存庫支援的唯一版本控制系統。支援的版本控制系統如下
- Git: git-scm.com
- Subversion: subversion.apache.org
- Mercurial: mercurial-scm.org
- Fossil: fossil-scm.org
要從這些系統取得套件,你需要安裝它們各自的客戶端。這可能造成不便。因此,支援 GitHub 和 Bitbucket,它們使用這些網站提供的 API,在不需安裝版本控制系統的情況下擷取套件。VCS 儲存庫為它們提供以 zip 格式擷取套件的「dist」。
- GitHub: github.com (Git)
- Bitbucket: bitbucket.org (Git)
要使用的 VCS 驅動程式會根據 URL 自動偵測。不過,如果你需要自行指定驅動程式,你可以使用 bitbucket、github、gitlab、perforce、fossil、git、svn 或 hg 作為儲存庫類型,而不是 vcs。
如果你將 GitHub 儲存庫的 no-api 金鑰設為 true,它會將儲存庫複製到其他 git 儲存庫,而不是使用 GitHub API。但是,與直接使用 git 驅動程式不同,Composer 仍然會嘗試使用 GitHub 的 zip 檔案。
請注意
- 若要讓 Composer 選擇要使用的驅動程式,必須將儲存庫類型定義為「vcs」
- 如果你已經使用私有存放庫,這表示 Composer 應該將它 cloned 到快取中。如果你要安裝相同套件與驅動程式,請務必執行下列命令
composer clearcache
再接composer update
,以更新 Composer 快取並從 dist 安裝套件。 - VCS 驅動程式
git-bitbucket
已不被支援,建議使用bitbucket
Bitbucket 驅動程式設定#
請注意,Bitbucket 的存放庫終端點必須是 https,而非 git。
設定完 Bitbucket 存放庫後,你也需要 設定驗證。
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
,你可以透過將 "package-path"
選項設為子目錄的方式,讓 Composer 存取它,在此範例中會是 "package-path": "foo/bar/"
。
如果你有一個私人 Subversion 存放庫,你可以在設定檔的 http-basic 區段儲存認證資料(請參閱 Schema)
{
"http-basic": {
"svn.example.org": {
"username": "username",
"password": "password"
}
}
}
如果你的 Subversion 伺服器預設設定為儲存認證資料,這些認證資料會儲存給目前使用者,而且此伺服器的現有已儲存認證資料會被覆寫。變更此行為的方式是在存放庫設定檔中設定 "svn-cache-credentials"
選項
{
"repositories": [
{
"type": "vcs",
"url": "http://svn.example.org/projectA/",
"svn-cache-credentials": false
}
]
}
套件#
如果你要使用某個專案,但它不透過上述任何方式支援 Composer,你仍然可以使用 package
存放庫,自己定義套件。
基本上,你定義的資訊會寫在 composer
存放庫的 packages.json
中,但只針對單一套件。同樣地,必填欄位為 name
、version
,以及 dist
或 source
之一。
以下是 smarty 範本引擎的範例
{
"repositories": [
{
"type": "package",
"package": {
"name": "smarty/smarty",
"version": "3.1.7",
"dist": {
"url": "https://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 部分,因為你不需要它。
如果包含了 source 鍵,reference 欄位應該是將要安裝的版本參考。type 欄位是 git
的話,這會是 commit ID、分支或標記的名称。
備註:不建議將 git 分支名稱用於 reference 欄位。雖然這是有效的,因為
git checkout
支援這個,但分支名稱是可以變動的,因此無法鎖定。
當類型欄位是 svn
時,參考欄位應該包含執行 svn co
時附加到 URL 的參考。
注意:這個儲存庫類型有一些限制,並且應儘量避免使用。
- 在您變更
version
欄位之前,Composer 不會更新套件。- Composer 不會更新提交參考,因此如果您使用
master
作為參考,您必須刪除套件才能强制更新,並且必須處理不穩定的鎖定檔。
package
儲存庫中的 "package"
鍵可以設定為陣列以定義套件的許多版本。
{
"repositories": [
{
"type": "package",
"package": [
{
"name": "foo/bar",
"version": "1.0.0",
...
},
{
"name": "foo/bar",
"version": "2.0.0",
...
}
]
}
]
}
自行主機#
雖然您可能大部分時間都想將套件放在 packagist 上,但有一些使用案例適用於自行主機您的儲存庫。
-
私有公司套件:如果您是使用 Composer 內部套件的公司的一份子,您可能想讓這些套件保持私密。
-
獨立生態系統:如果您有一個有其自己的生態系統的專案,而且該套件實際上無法被更大的 PHP 社群重複使用,您可能想讓它們獨立於 packagist。WordPress 外掛就是一個範例。
建議為自行主機您的套件,使用 composer
類型的儲存庫,它可以提供最佳效能。
有幾個工具可以協助您建立 composer
儲存庫。
私用 Packagist#
私用 Packagist 是主機或自行主機的應用程式,提供私用套件主機,以及 GitHub、Packagist.org 以及其他套件儲存庫的鏡像。
請查看 Packagist.com 以取得更多資訊。
Satis#
Satis 是靜態 composer
儲存庫產生器。它有點像超輕量、靜態的 packagist 檔案版本。
您給它一個包含儲存庫的 composer.json
,通常是 VCS 和套件儲存庫定義。它會找尋所有 require
的套件,並卸載您的 composer
儲存庫的 packages.json
。
請查看 satis GitHub 儲存庫,以及 處理私有套件的文章 以取得更多資訊。
Artifact#
在某些情況下,無法有先前提到的任何一種線上儲存庫類型,甚至是 VCS。跨組織函式庫透過建置成果進行交換就是一個典型的範例。當然,大部分時間,這些都是私有的。要使用這些檔案,可以使用類型為 artifact
的儲存庫,其中包含資料夾,裡面有那些私有套件的 ZIP 或 TAR 檔案。
{
"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 檔案都是一個 ZIP 儲存庫,其根資料夾中含有一個 composer.json
檔案
unzip -l acme-corp-parser-10.3.5.zip
composer.json
...
如果有多個封存檔案包含不同版本的套件,那麼它們會一起匯入。當封存檔案夾中新增了一個具有較新版本的封存檔案時,如果您執行 更新
,那麼該版本也會一起匯入,而且 Composer 會更新為最新版本。
路徑#
除了存放庫中的人工製品之外,您還可以相依於一個本機目錄 (絕對路徑或相對路徑),這個部分是其中一個,這對於處理單一大型儲存庫時特別有用。
例如,如果您在儲存庫中具有下列目錄結構
...
├── apps
│ └── my-app
│ └── composer.json
├── packages
│ └── my-package
│ └── composer.json
...
然後,若要在您的 apps/my-app/composer.json
檔案中新增套件 my/package
作為相依性項,您可以使用下列組態
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package"
}
],
"require": {
"my/package": "*"
}
}
如果套件是一個本機版本控制系統 (VCS) 儲存庫,那麼版本可以根據目前檢出的分支或標籤來推測。否則,這個版本應該要明確定義在套件的 composer.json
檔案中。如果版本無法經由這些方法解決,則假設它是 dev-master
。
當無法從本機版本控制系統 (VCS) 儲存庫中推測版本,或者您想要覆寫版本時,您可以在宣告儲存庫時使用 versions
選項
{
"repositories": [
{
"type": "path",
"url": "../../packages/my-package",
"options": {
"versions": {
"my/package": "4.2-dev"
}
}
}
]
}
如果可能,會將本機套件建立符號連結,如果是這樣,主控台上的輸出內容會顯示 從 ../../packages/my-package 進行符號連結
。如果無法建立符號連結,套件會複製過去。在這種情況下,主控台會輸出 從 ../../packages/my-package 複製
。
除了預設的備用策略之外,您可以使用 "symlink": true
強制使用符號連結或使用 "symlink": false
選項進行鏡像。強制鏡像在從一個大型儲存庫部署或生成套件時非常有用。
請注意:在 Windows 系統中,目錄符號連結已透過 NTFS 交接點來實作,這是因為非管理員使用者可以建立交接點。在 Windows 7 以下的版本或已停用
proc_open
時,系統始終會使用鏡像。
{
"repositories": [
{
"type": "path",
"url": "../../packages/*",
"options": {
"symlink": false
}
}
]
}
起始連字符會擴充為目前使用者的家目錄,而環境變數的解析過程會在 Windows 及 Linux/Mac 標記法中同時進行。例如,~/git/mypackage
會自動載入來自 /home/<username>/git/mypackage
的 mypackage 克隆,與 $HOME/git/mypackage
或 %USERPROFILE%/git/mypackage
等同。
請注意:儲存庫路徑也可以包括萬用字元,例如
*
及?
。有關詳細資料,請參閱 PHP glob 函數。
您可以組態套件的 dist 參考 (出現在 composer.lock 檔案中) 建置方式。
有下列模式
none
- 參考永遠都是空的。這有助於減少鎖定檔案中的鎖定檔案衝突,但會降低對於最後一次更新時間及套件是否是最新的狀態的清楚程度。config
- 參考根據套件的 composer.json 雜湊和儲存庫設定建立auto
(預設使用) - 參考根據像config
中的雜湊建立,但如果套件資料夾包含 git 儲存庫,則 HEAD commit 的雜湊會作為參考。
{
"repositories": [
{
"type": "path",
"url": "../../packages/*",
"options": {
"reference": "config"
}
}
]
}
停用 Packagist.org#
您可以將此新增至 composer.json
來停用預設的 Packagist.org 儲存庫
{
"repositories": [
{
"packagist.org": false
}
]
}
您可以使用全域設定旗標來全域停用 Packagist。org
php composer.phar config -g repo.packagist false
發現錯別字?此文件中有些錯誤?分岔並編輯它!