composer 是PHP5.3以上的一個依賴管理工具。它允許你聲明項目所依賴的代碼庫,它會在你的項目中為你安裝他們。Composer 不是一個包管理器。是的,它涉及"packages" 和"libraries",但它在每個項目的基礎上進行管理,在你項目的某個目錄中(例如vendor)進行安裝。默認情況下它不會在全局安裝任何東西。
Composer是一個非常流行的PHP包依賴管理工具,已經取代PEAR包管理器,對於PHP開發者來說掌握Composer是必須的.
對於使用者來說Composer非常的簡單,通過簡單的一條命令將需要的代碼包下載到vendor目錄下,然後開發者就可以引入包並使用了.
其中的關鍵在於你項目定義的composer.json,可以定義項目需要依賴的包(可能有多個),而依賴的包可能又依賴其他的包(這就是組件的好處),這些都不用你煩心, Composer會自動下載你需要的一切,一切在於composer.json的定義.
Composer對於使用者來說是很透明,但是其背後的理念還是需要了解一下的,其的誕生也不是偶然的,得益於Github的快速發展,PHP語言也越來越現代化,顯得更高大上了.
為了理解Composer,先大概了解下其結構:
Composer的結構
-
Composer命令行工具 :
這個理解就比較簡單了,通過使用者定義的Composer.json去下載你需要的代碼,假如只是簡單的使用Composer,那麼掌握一些具體命令就完全可以了 -
Autoloading代碼加載器 :
通過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,你只需要下載composer.phar
可執行文件。
curl -sS https://getcomposer.org/installer | php
詳細請查看簡介章節。
要檢查Composer是否正常工作,只需要通過php
來執行PHAR:
php composer.phar
這將返回給你一個可執行的命令列表。
注意:你也可以僅執行
--check
選項而無需下載Composer。要獲取更多的信息請使用--help
。curl -sS https://getcomposer.org/installer | php -- --help
composer.json
:項目安裝
要開始在你的項目中使用Composer,你只需要一個composer.json
文件。該文件包含了項目的依賴和其它的一些元數據。
這個JSON format 是很容易編寫的。它允許你定義嵌套結構。
關於require
Key
第一件事情(並且往往只需要做這一件事),你需要在composer.json
文件中指定require
key的值。你只需要簡單的告訴Composer你的項目需要依賴哪些包。
{
"require": {
"monolog/monolog": "1.0.*"
}
}
你可以看到,require
需要一個包名稱(例如monolog/monolog
)映射到包版本(例如1.0.*
)的對象。
包名稱
包名稱由供應商名稱和其項目名稱構成。通常容易產生相同的項目名稱,而供應商名稱的存在則很好的解決了命名衝突的問題。它允許兩個不同的人創建同樣名為json
的庫,而之後它們將被命名為igorw/json
和seldaek/json
。
這裡我們需要引入monolog/monolog
,供應商名稱與項目的名稱相同,對於一個具有唯一名稱的項目,我們推薦這麼做。它還允許以後在同一個命名空間添加更多的相關項目。如果你維護著一個庫,這將使你可以很容易的把它分離成更小的部分。
包版本
在前面的例子中,我們引入的monolog版本指定為1.0.*
。這表示任何從1.0
開始的開發分支,它將會匹配1.0.0
、1.0.2
或者1.0.20
。
版本約束可以用幾個不同的方法來指定。
PHP | ||
---|---|---|
下一個重要版本(波浪號運算符)
~
最好用例子來解釋:~1.2
相當於>=1.2,<2.0
,而~1.2.3
相當於>=1.2.3,<1.3
。正如你所看到的這對於遵循語義化版本號的項目最有用。一個常見的用法是標記你所依賴的最低版本,像~1.2
(允許1.2以上的任何版本,但不包括2.0)。由於理論上直到2.0應該都沒有向後兼容性問題,所以效果很好。你還會看到它的另一種用法,使用~
指定最低版本,但允許版本號的最後一位數字上升。
注意:雖然
2.0-beta.1
嚴格地說是早於2.0
,但是,根據版本約束條件,例如~1.2
卻不會安裝這個版本。就像前面所講的~1.2
只意味著.2
部分可以改變,但是1.
部分是固定的。
穩定性
默認情況下只有穩定的發行版才會被考慮在內。如果你也想獲得RC、beta、alpha或dev版本,你可以使用穩定標誌。你可以對所有的包做最小穩定性設置,而不是每個依賴逐一設置。
安裝依賴包
獲取定義的依賴到你的本地項目,只需要調用composer.phar
運行install
命令。
php composer.phar install
接著前面的例子,這將會找到monolog/monolog
的最新版本,並將它下載到vendor
目錄。這是一個慣例把第三方的代碼到一個指定的目錄vendor
。如果是monolog將會創建vendor/monolog/monolog
目錄。
小技巧:如果你正在使用Git來管理你的項目,你可能要添加
vendor
到你的.gitignore
文件中。你不會希望將所有的代碼都添加到你的版本庫中。
另一件事是install
命令將創建一個composer.lock
文件到你項目的根目錄中。
composer.lock
- 鎖文件
在安裝依賴後,Composer將把安裝時確切的版本號列表寫入composer.lock
文件。這將鎖定改項目的特定版本。
請提交你應用程序的composer.lock
(包括composer.json
)到你的版本庫中
這是非常重要的,因為install
命令將會檢查鎖文件是否存在,如果存在,它將下載指定的版本(忽略composer.json
文件中的定義)。
這意味著,任何人建立項目都將下載與指定版本完全相同的依賴。你的持續集成服務器、生產環境、你團隊中的其他開發人員、每件事、每個人都使用相同的依賴,從而減輕潛在的錯誤對部署的影響。即使你獨自開發項目,在六個月內重新安裝項目時,你也可以放心的繼續工作,即使從那時起你的依賴已經發布了許多新的版本。
如果不存在composer.lock
文件,Composer將讀取composer.json
並創建鎖文件。
這意味著如果你的依賴更新了新的版本,你將不會獲得任何更新。此時要更新你的依賴版本請使用update
命令。這將獲取最新匹配的版本(根據你的composer.json
文件)並將新版本更新進鎖文件。
php composer.phar update
如果只想安裝或更新一個依賴,你可以白名單它們:
php composer.phar update monolog/monolog [...]
注意:對於庫,並不一定建議提交鎖文件請參考:庫的鎖文件.
Packagist
packagist 是Composer的主要資源庫。一個Composer的庫基本上是一個包的源:記錄了可以得到包的地方。Packagist的目標是成為大家使用庫資源的中央存儲平台。這意味著你可以require
那裡的任何包。
當你訪問packagist website (packagist.org),你可以瀏覽和搜索資源包。
任何支持Composer 的開源項目應該發布自己的包在packagist 上。雖然並不一定要發佈在packagist 上來使用Composer,但它使我們的編程生活更加輕鬆。
自動加載
對於庫的自動加載信息,Composer生成了一個vendor/autoload.php
文件。你可以簡單的引入這個文件,你會得到一個免費的自動加載支持。
require 'vendor/autoload.php';
這使得你可以很容易的使用第三方代碼。例如:如果你的項目依賴monolog,你就可以像這樣開始使用這個類庫,並且他們將被自動加載。
$log = new Monolog\Logger('name');$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));$log->addWarning('Foo');
你可以在composer.json
的autoload
字段中增加自己的autoloader。
{
"autoload": {
"psr-4": {"Acme\\": "src/"}
}
}
Composer將註冊一個PSR-4 autoloader到Acme
命名空間。
你可以定義一個從命名空間到目錄的映射。此時src
會在你項目的根目錄,與vendor
文件夾同級。例如src/Foo.php
文件應該包含Acme\Foo
類。
添加autoload
字段後,你應該再次運行install
命令來生成vendor/autoload.php
文件。
引用這個文件也將返回autoloader 的實例,你可以將包含調用的返回值存儲在變量中,並添加更多的命名空間。這對於在一個測試套件中自動加載類文件是非常有用的,例如。
$loader = require 'vendor/autoload.php';$loader->add('Acme\\Test\\', __DIR__);
除了PSR-4自動加載,classmap也是支持的。這允許類被自動加載,即使不符合PSR-0規範。詳細請查看自動加載-參考。
注意: Composer提供了自己的autoloader。如果你不想使用它,你可以僅僅引入
vendor/composer/autoload_*.php
文件,它返回一個關聯數組,你可以通過這個關聯數組配置自己的autoloader。
Composer命令行工具
composer init
使用者可以在自己的項目下創建composer.json以便定義你項目的依賴包,也可以通過composer init交互式的創建composer.json.
composer install
應該是最常用的命令,composer會根據本地的composer.json安裝包,將下載的包放入項目下的vendor目錄下,同時將安裝時候的包版本信息放入到composer.lock,以便鎖定版本.
其實在install的時候,假如發現composer.lock版本和目前vendor目錄下的代碼版本是一致的,則Composer會什麼也不做,composer.lock的目的就是讓你安心在目前這個版本下工作,而不獲取最新版本的包.
composer update
那麼如何更新composer.lock以便獲取到最新版本的包呢?通過這個命令即可更新最新版本的包
composer config
這個命令還是建議了解下,全局的配置保存在COMPOSER_HOME/config.json,非全局的配置信息則存儲在本項目目錄下.
composer create-project
這個命令不常用,但是個人覺得還是很重要的,使用普通的install命令是將項目所有的依賴包下載到本項目vendor目錄下.而通過這個命令則是將所有的代碼及其依賴的包放到一個目錄下,相當於執行了一個git clone命令,一般是包的開發者可能為了修復bug會使用該命令.
composer global
這是一個全局的安裝命令,它允許你在COMPOSER_HOME目錄下執行Composer的命令,比如install,update.當然你的COMPOSER_HOME要在$PATH環境下.
比如執行composer global require fabpot/php-cs-fixer,現在php-cs-fixer命令行可以全局運行了,如果稍後想更新它,只需要運行composer global update
composer dump-autoload
當你修改項目下的composer.json的文件,並不一定要運行composer update命令進行更新,有的時候可以使用該命令來更新加載器,比如你要引用本地自定義的包(不是來自於packagist) ,後面會通過實踐來說明該命令.
composer require
假如手動或者交互式創建composer.json文件,可以直接使用該命令來安裝包
–prefer-source和–prefer-dist參數
–prefer-dist:對於穩定的包來說,一般Composer安裝默認使用該參數,這也能加快安裝,比如有可能直接從packagist安裝了相應的包,而不用實際去Github上下載包.
–prefer-source:假如使用該參數,則會直接從Github上安裝,安裝包後vendor目錄下還含有.git信息
如何給Composer添加代理
在國內使用Composer下載特別慢,可以通過二個方法進行加速
-
composer config repo.packagist composer “https://packagist.phpcomposer.com“
-
編輯composer.json
Autoloading代碼加載器
composer本身集成一個autoloader,支持PSR-4,PSR-0,classmap,files autoloading.
這里通過一個例子來說明通過Composer如何引用classmap,files,本地符合PSR-4標準的代碼
編輯composer.json
composer dump-autoload
通過上述的操作,對於PSR-4來說等同註冊了一個PSR-4 autoloader(從FooBar命名空間)
假如不想使用Composer的autoloader,可以直接包含vendor/composer/autoload_*.php文件,配置自己的加載器.
具體的例子託管在github上,可參考.
Repositories
關於Repositories,了解其不是必須的,但是假如掌握則更能理解Composer,對於Repositories,其中文文檔和英文文檔解釋的很好,這裡也進行了一些摘抄 .
基本概念
包:
Composer是一個依賴管理工具,它在本地安裝一些資源包和包的描述(比如包名稱和對應的版本),比較重要的元數據描述是dist和source,dist指向一個存檔,該存檔是對一個資源包的某個版本的數據進行的打包.source指向一個開發中的源,這通常是一個源代碼倉庫(比如git)
資源庫:
一個資源庫是一個包的來源.它是一個packages/versions的列表.
Composer將查看所有你定義的repositories以找到項目需要的資源包(這句話很重要).
默認情況下已經將Packagist.org註冊到Composer(或者理解為Packagist.org是Composer資源庫默認的倉庫類型)
Composer資源庫類型
Composer資源庫包括四種類型,默認的是composer類型,也就是packagist.org所使用的資源類型.
它使用一個單一的packages.json文件,包含了所有的資源包元數據.當你將包發佈到pckagist.org上,則默認系統會創建一個packages.json,不過我沒有找到我的包對應的文件.
VCS資源庫類型
假如你想構建一個私有的Composer私有資源庫類型,可以使用該類型,這裡舉一個例子,比如你在自己項目的composer.json定義如下,則就可以使用對應的Github上的代碼了.
當運行composer update的時候,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包,取決於它的上下文,比如你git clone ywdblog/phpcomposer,則這時候本地phpcomposer目錄就是ROOT包,假如你在本地phpcomposer目錄下composer require ywdblog/phpcomposer,則這時候你的項目phpcomposer就是ROOT包.
了解composer-schema.json可參考該網址,Laravel作為一個成熟的框架,其定義的composer.json非常經典
關於包的版本
當使用者在本地配置composer.json的時候,可以指定需要包的特定版本,Composer支持從Github倉庫中下載Tag或者分支下的包.
對於Github上的Tag來說,Packagist會創建對應包的版本,它符合XYZ,vX.YZ,XYZ-包類型,就是說Github上雖然只有一個特定版本的包,但Composer支持多種形式的引用方式,比如:
對於Github上的分支來說,Packagist會創建對應包的版本,假如分支名看起來像一個版本,將創建{分支名}-dev的包版本號,如果分支名看起來不像一個版本號,它將會創建dev-{分支名}形式的版本號
總結:
理解Composer,最重要的是實踐,最後也能明白PSR-4和命名空間,也可以嘗試將你的項目發佈到pckagist.org上 .