概述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 } ] }