一、什麼是Composer?
Composer 是 PHP 中的依賴管理工具。它允許聲明項目所依賴的庫,並且它將為您管理(安裝/更新)它們。
二、如何安裝?
Linux 系統和 MacOS 系統
直接下載最新穩定版:
然後執行下列命令,放到/usr/local/bin下面
sudo mv composer.phar /usr/local/bin/composer
sudo chmod +x /usr/local/bin/composer
執行composer -V 查看是否安裝成功
Windows系統
第一步也是下載最新穩定版,然後基於 composer.phar文件創建 composer.bat文件
- 使用cmd時,執行:
echo @php "%~dp0composer.phar" %*>composer.bat
- 使用PowerShell時,執行:
Set-Content composer.bat '@php "%~dp0composer.phar" %*'
composer.bat文件所在的目錄要配到環境變量中,然後才能執行 composer -V,所以一般建議可以直接放到php的可執行目錄中。
三、composer.json VS composer.lock
什麼是composer.json?
composer.json文件是composer使用json格式描述項目依賴的配置文件,其中包含一些項目元數據及其依賴配置等。
什麼是composer.lock?
composer.lock文件是composer安裝完依賴後,生成的版本鎖定文件,以確保在項目中工作的每個人的包版本一致。
兩者應用場景
當項目第一次初始化時,需要運行 update 命令,composer從composer.json文件查找依賴項,獲取依賴的版本並寫入到composer.lock文件中,最後隱式調用 install 命令,下載所有依賴包默認放到項目根目錄的vendor目錄中,composer.lock文件應該提交到版本控制系統中,例如:git。
當項目已經初始化過,其他人員拉取項目,安裝依賴,只需要執行 install 命令,composer會從composer.lock中獲取依賴項來下載依賴包。
如果想要更新依賴包版本,需要執行 update 命令,composer會更新composer.json和composer.lock文件,並下載最新的依賴包。
四、什麼是Autoloading(自動加載)?
對於指定自動加載信息的庫,Composer 會生成一個vendor/autoload.php 文件,然後引入依賴包時,只需要使用 require __DIR__ . '/vendor/autoload.php';,不用 require 單獨引入使用的包。
例如:
require __DIR__ . '/vendor/autoload.php';
$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->warning('Foo');
五、什麼是PSR0、PSR4、classmap?
PSR0示例:
lib/abc/src/Test2.php 文件命名空間是 abc\src
那麼在 composer.json 文件中的 autoload 項 psr-0 節點要把命名空間配在鍵上面,值要配最外層目錄,此處為 lib,一般 composer 包的話是 vendor;
{
"autoload": {
"psr-0": {
"abc\\src": "lib/"
}
}
}
autoload 加載規則是拼接 lib 為路徑前綴,即:/lib/abc/src;
composer.json 加上配置後,要使用 composer dump-autoload 生成位於 vendor 目錄中的 psr0 自動加載文件
注意:psr0 生成的是 autoload_namespaces.php ,psr4 生成的是 autoload_psr4.php,然後就可以從其他文件中訪問了。
例如:訪問 abc/src/Test2.php ,即查找 /lib/abc/src/Test2.php 。
如圖在 app/sms/src/Test.php 要想訪問 Test2.php ,首先用 require_once加載 autoload.php,然後就可以訪問了。
PSR4示例:
lib2/abc/src/Test3.php 命名空間是 Lib2\Abc
那麼在 composer.json 文件的 autoload 項 psr-4 節點要把命名空間配到鍵上面,文件全路徑配到值上面,則 composer 在解析 Lib2/Abc 時,會找到 lib2/abc/src 裏面的文件。
再次執行 composer dump-autoload 生成 autoload_psr4.php 文件內容
從 Test.php 中訪問 Test3.php 中的方法:
以上示例基本就能理解PSR-0、PSR-4到底是怎麼用了,PSR官方的文檔一言難盡。
classmap示例:
classmap 是 composer 使用的簡單類映射,用於在沒有遵循PSR-0/4規範的模塊或類文件時,通過配置自動加載。
classmap 還支持通配符的路徑方式,例如:
{
"autoload": {
"classmap": ["src/addons/*/lib/", "3rd-party/*", "Something.php"]
}
}
直接在 autoload 的 classmap 屬性鍵下配置需要自動加載的目錄或文件,當然也需要再次執行 composer dump-autoload,會在 autoload_classmap.php 文件中生成映射內容。
然後就可以在其他類直接使用了:
六、常用命令
- 列出完整命令列表
composer 或
composer list
--verbose (-v):打印詳細信息
示例:
# 一個v正常打印輸出,兩個v打印更多信息,三個v為debug模式
composer update -v
composer update -vv
composer update -vvv
--help (-h):打印幫助信息
示例:
composer -h
--quiet (-q):靜音模式,不輸出任何信息
示例:
composer update -q
--no-interaction (-n):非交互式模式,不詢問任何問題
示例:
composer update -n
-no-plugins:禁用插件
示例:
composer install --no-plugins
--no-scripts:跳過定義在composer.json中的腳本執行
示例:
composer install --no-scripts
--no-cache:禁用使用緩存目錄
示例:
composer install --no-cache
--profile:顯示時間和內存使用信息
示例:
composer install --profile
--version (-V):打印版本信息
示例:
composer -V
init:初始化composer.json文件,交互式詢問填充的值
示例:
composer init
install或i:安裝依賴包
如果沒有composer.lock文件,則composer讀取composer.json文件,下載並安裝依賴包到vendor目錄,最後創建composer.lock文件。
如果已存在composer.lock文件,則composer從composer.lock文件中讀取依賴版本進行安裝,以此保證每個人安裝的包版本是一致的。
示例:
composer install
常用的選項:
--prefer-install:選擇從可發佈版的包(dist)還是從源碼(source)下載,默認是dist,下載源碼一般用於貢獻開源、bug修復等。
示例:
composer install --prefer-install=source
--dry-run:模擬下載安裝過程,不實際安裝包
示例:
composer install --dry-run
實際上是做了一個包兼容性檢查,最後少了實際下載安裝過程。
--dev:也安裝列在 require-dev 鍵指定的開發所需的包,此為默認行為--no-dev:跳過安裝在 require-dev 鍵指定的開發所需的包。
示例:
composer i --no-dev
update 或 u 或 upgrade:
更新依賴包版本,然後更新composer.json和composer.lock文件。
示例:
# 更新所有包
composer update
# 更新指定的包,可以一次性指定多個
composer update monolog/monolog guzzlehttp/guzzle
require 或 r
添加依賴包,如果composer.json存在,則添加依賴包版本約束;如果composer.json不存在,則自動創建。
示例:
# 如果require後面不指定依賴包名,則composer會提示你輸入包名來搜索
composer require
# 指定依賴包名即版本約束,注意版本帶點:".",要用雙引號括起來,否則命令行會解析失敗
composer require "monolog/monolog:3.0.*" "symfony/console:7.0.*"
# 只指定依賴包名,不指定版本約束,composer會基於可用的包版本、已安裝的其他依賴包、php版本來選擇合適的版本。
composer require monolog/monolog symfony/console
常用的選項:
--dev:添加包到require-dev指令項。--dry-run:同上。--prefer-install:同上。
remove或rm或uninstall:
移除在composer.json中指定的依賴包,同時更新composer.lock文件,並卸載/刪除包文件。
示例:
composer remove monolog/monolog symfony/console
常用的選項:
--unused:移除未使用的依賴包--dev:僅僅移除require-dev指定的依賴包--dry-run:同上。
reinstall:重新安裝依賴包
一般用於依賴包源文件被修改了,想復原,或者想安裝發佈版本或源碼版本。
示例:
composer reinstall monolog/monolog symfony/console
check-platform-reqs:檢查PHP版本和擴展是否匹配依賴包的版本
示例:
composer check-platform-reqs
常用的選項:
--lock:僅僅從composer.lock文件中獲取依賴包--no-dev:禁用檢查require-dev指令項列出的包--format或-f:格式化輸出,默認是text,可以為json。
global:對包進行全局管理,例如:安裝、更新、移除等。
安裝的包在 COMPOSER_HOME composer家目錄下面的vendor目錄
示例:
composer global require monolog/monolog symfony/console
search:指定包名搜索依賴包,默認從packagist倉庫搜索結果。
示例:
composer search monolog/monolog symfony/console
show或info:列出項目已安裝的所有可用的包
示例:
# 顯示所有
composer show
# 指定包
composer show monolog/monolog symfony/console
常用的選項:
--self或-s:僅僅列出根包的信息,即當前的composer.json文件中的信息。--tree或-t:以樹形結構顯示包的依賴關係。
--latest或-l:列出所有安裝的包和最新的版本。--outdated或-o:僅僅列出有新版本可用的包。
outdated:列出具有可用更新的已安裝軟件包的列表,顯示出當前的版本和最新的版本,此命令為:composer show -lo的別名。
示例:
composer outdated
輸出內容的顏色有如下含義:
green (=):依賴項當前版本就是最新版本
yellow (~):依賴項有一個可用的新版本,其中包括根據語義的向後兼容性中斷,因此請儘可能升級。
red (!):依賴項有一個語義兼容的新版本,應該要升級了。
browse或home:調用瀏覽器打開依賴包的倉庫地址或主頁。
示例:
composer browse
suggests:列出所有包或指定包的的建議。
示例:
# 默認列出所有包的建議
composer suggests
# 列出指定包的建議
composer suggests monolog/monolog
depends / why:哪些其他包依賴於指定的包。
常用選項:
--recursive或-r:遞歸解析到根包。--tree或-t:打印樹狀結構,使用-t時會隱式調用-r。
示例:
# 正常輸出被依賴的包
composer depends psr/log
# 以樹形結構輸出被依賴的包
composer depends -t psr/log
prohibits或why-not:查找是否能安裝指定版本的包,可能有其他包依賴此包的當前版本,所以不能升級到新版本。
常用選項:
--recursive或-r:遞歸解析到根包。--tree或-t:打印樹狀結構,使用-t時會隱式調用-r。
示例:
composer prohibits symfony/symfony 3.1
laravel/framework v5.2.16 requires symfony/var-dumper (2.8.*|3.0.*)
validate:檢查composer.json文件是否有json語法錯誤。
示例:
composer validate
status:如果依賴包是從源碼安裝的,則在本地對依賴包的源碼進行了更改,則使用status可以檢測出代碼有哪些改動,類似於git的status。
示例:
# 簡單輸出改動的地方
composer status
# 詳細輸出改動的信息,使用-v或--verbose
composer status -v
You have changes in the following dependencies:
vendor/seld/jsonlint:
M README.mdown
self-update或selfupdate:更新composer本身到最新版本,或者指定一個版本進行更新。
常用的選項:
--rollback或-r:回退到上一個版本--clean-backups:刪除所有舊版本的備份,緩存中現僅存當前版本,所以不能回退了。
示例:
composer self-update
config:列出composer的配置項或修改配置。
修改配置的話建議直接編輯配置文件,在命令行多個配置項連在一塊容易混亂。
全局配置文件路徑:$COMPOSER_HOME/config.json,$COMPOSER_HOME 表示 composer 的目錄,所以真實路徑一般為: ~/.composer/config.json
項目單個配置文件,則為 composer.json 了。
常用的選項:
--list或-l:列出當前的配置項,包括當前項目和全局的,如果指定了--global則只列出全局的配置項。--unset:移除指定的配置項。
示例:
#列出所有配置項
composer config --list
# 移除指定的配置項
composer config --unset repositories
create-project:下載依賴包作為項目來開發,其實質意義與git clone拉取源代碼大致相同。
示例:
# 依賴包後面可以指定安裝後的項目名,此處為:doctrine_orm,也可以在項目名後指定版本,不指定默認安裝最新版本。
composer create-project doctrine/orm doctrine_orm
dump-autoload 或 dumpautoload:在自定義添加了PSR-0或PSR-4的類映射後,需要執行此命令重新生成在vendor目錄中的autoload_namespaces.php或autoload_psr4.php文件。
示例:
composer dump-autoload
clear-cache 或 clearcache 或 cc:刪除composer緩存目錄中的所有內容。
示例:
composer clear-cache
run-script 或 run:運行用户定義的腳本。
常用選項:
--list 或 -l:列出用户定義的腳本
示例:
# 列出用户定義的腳本
composer run-script -l
# 運行指定的腳本
composer run-script script1
diagnose:診斷composer出現的bug和一些奇怪的問題。
示例:
composer diagnose
archive:把項目打成壓縮包,且把忽略的文件排除在外。
常用的選項:
--format 或 -f:指定壓縮包的格式,有:tar, tar.gz, tar.bz2, zip,默認是tar。--dir:指定壓縮包寫入的目錄名,默認是當前目錄:.。--file:指定壓縮包的名稱,默認是依賴包的名稱。
示例:
composer archive vendor/package 2.0.21 --format=zip
help:打印幫助信息。
常用選項:
--format:指定格式,有txt, xml, json, md可用,默認是txt
示例:
composer help
# 指定子命令
composer help install
# 指定輸出的格式
composer help install md
七、composer.json 常用屬性(或者叫字段)解析
name:項目名或包名,例如:monolog/monolog。
包名的規則是:廠商名/包名,全小寫,多個單詞用 -、. 或 _ 分割。
如果當前包已經發布過了,則name屬性必須填寫。
description:包名的描述。version:包的版本,一般建議不寫,composer可以從包倉庫中自動推斷。
版本規則:X.Y.Z 或 vX.Y.Z,可接的後綴有:-dev, -patch (-p), -alpha (-a), -beta (-b), -RC
示例:
1.0.2
1.0.2-dev
v.2.0.2-dev
type:包的類型,默認是:library。
library:表示包是類庫項目,會安裝到vendor目錄project:表示包是標準應用項目。
keywords:包相關的關鍵詞數組,用於後續搜索可過濾,可選。
示例:
"keywords": [
"yii2",
"api",
"framework",
"templating"
]
homepage:項目網站URL,或 packagist 上的URL位置,可選。license:包的許可聲明,可以是單個字符串為或字符串數組。
常見的license有:
- Apache-2.0
- BSD-2-Clause
- BSD-3-Clause
- BSD-4-Clause
- GPL-2.0-only / GPL-2.0-or-later
- GPL-3.0-only / GPL-3.0-or-later
- LGPL-2.1-only / LGPL-2.1-or-later
- LGPL-3.0-only / LGPL-3.0-or-later
- MIT
示例:
// 單個license
{
"license": "MIT"
}
// 多個license,或的關係,通過數組指定
{
"license": [
"LGPL-2.1-only",
"GPL-3.0-or-later"
]
}
// 多個license,或的關係,也可以用()加or來指定
{
"license": "(LGPL-2.1-only or GPL-3.0-or-later)"
}
// 如果多個license,是且的關係,則用and來指定
{
"license": "(LGPL-2.1-only and GPL-3.0-or-later)"
}
authors:指定包的作者,此屬性是一個對象數組,每個對象可包括以下屬性:
name:作者名字email:郵箱homepage:站點主頁role:作者在這個項目擔任的角色
示例:
{
"authors": [
{
"name": "Nils Adermann",
"email": "naderman@naderman.de",
"homepage": "https://www.naderman.de",
"role": "Developer"
},
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "https://seld.be",
"role": "Developer"
}
]
}
require:依賴的包。
示例:
{
"require": {
"monolog/monolog": "1.0.*"
}
}
require-dev:僅開發期間或運行測試時所需的依賴包。
{
"require-dev": {
"monolog/monolog": "1.0.*"
}
}
conflict:指定與依賴包所衝突的包,composer不會安裝此處指定的包。
示例:
{
"conflict": {
"monolog/monolog": "1.0.*"
}
}
suggest:可以增強此軟件包或與此軟件包配合良好的建議軟件包,在安裝包後顯示,以提示用户可以添加更多包,即使它們不是嚴格要求的。
示例:
{
"suggest": {
"monolog/monolog": "Allows more advanced logging of the application flow",
"ext-xml": "Needed to support XML format in class Foo"
}
}
autoload:自動加載映射,包括主要的PSR-0、PSR-4、classmap,如上所述。
還包括:
exclude-from-classmap:指定自動加載排除的目錄或文件
示例:
{
"autoload": {
"exclude-from-classmap": ["/Tests/", "/test/", "/tests/"]
}
}
autoload-dev:定義僅在開發階段的自動加載規則
示例:
{
"autoload-dev": {
"psr-4": { "MyLibrary\\Tests\\": "tests/" }
}
}
repositories:指定包的倉庫,composer默認是使用packagist中心倉庫。
倉庫支持三種類型:
composer:類似packagist的倉庫。vcs:版本控制系統倉庫,如:git。package:當加載的是不支持composer的類庫項目,使用此選項。
示例:
{
"repositories": [
{
"type": "composer",
"url": "http://packages.example.com"
},
{
"type": "vcs",
"url": "https://github.com/Seldaek/monolog"
},
{
"type": "package",
"package": {
"name": "smarty/smarty",
"version": "3.1.7",
"dist": {
"url": "https://www.smarty.net/files/Smarty-3.1.7.zip",
"type": "zip"
}
}
}
]
}
也可以使用json對象提供倉庫名稱的方式來指定,例如:
{
"repositories": {
"foo": {
"type": "composer",
"url": "http://packages.foo.com"
},
// 通過指定倉庫名為:packagist,使用鏡像來覆蓋默認的倉庫地址
"packagist": {
"type": "composer",
"url": "https://mirrors.aliyun.com/composer/"
}
}
}
config:項目的配置項。
示例:
{
// 啓動指定的插件
"config": {
"allow-plugins": {
"third-party/required-plugin": true,
"my-organization/*": true,
"unnecessary/plugin": false
}
}
// 禁用所有插件
"config": {
"allow-plugins": false
}
// 啓用所有插件
"config": {
"allow-plugins": true
}
}
scripts:composer執行命令過程中的可執行一些腳本做輔助性的工作。
腳本可執行的條件要滿足以下條件:
- 腳本可包含PHP回調函數和命令行可執行命令。
- 包含已定義回調的 PHP 類和命令必須可通過 Composer 的自動加載功能自動加載。
- 回調只能從 psr-0、psr-4 和 classmap 定義自動加載類。如果定義的回調依賴於類外部定義的函數,則回調本身負責加載包含這些函數的文件。
腳本是需要 composer 預定義的事件來觸發的,常見的事件有:
pre-install-cmd:如果composer.lock文件存在,則在執行install命令之前被觸發。post-install-cmd:如果composer.lock文件存在,則在執行install命令之後被觸發。pre-update-cmd:在執行update命令之前觸發,或者當composer.lock文件不存在時,執行了install命令也會觸發。post-update-cmd:在執行update命令之後觸發,或者當composer.lock文件不存在時,執行了install命令也會觸發。pre-autoload-dump:當執行了install/update期間,或者執行了dump-autoload命令,在自動加載重新寫入配置文件之前觸發。post-autoload-dump:當執行了install/update期間,或者執行了dump-autoload命令,在自動加載重新寫入配置文件之後觸發。post-root-package-install:在執行了create-project時,在根包已經安裝完成後且正常的依賴沒有安裝之前時觸發。post-create-project-cmd:在執行了create-project命令後觸發。
參考學習 laravel 使用 scripts 的示例:
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
// 發佈靜態資源
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
],
"post-root-package-install": [
// 在執行了 create-project 後判斷有沒有.env文件,沒有則從 .env.example 複製一份為 .env文件
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi",
// 生成數據庫配置文件並執行遷移命令
"@php -r \"file_exists('database/database.sqlite') || touch('database/database.sqlite');\"",
"@php artisan migrate --graceful --ansi"
]
}
八、版本約束解析
指定具體的版本號
composer 會按照執行的版本進行安裝。
示例:
{
"require": {
"monolog/monolog": "3.6.0"
}
}
普通指定版本的範圍
有效的操作符為:>,>=, <, <=, !=
不同的操作符可以聯合在一起使用,如果是邏輯與的關係,使用空格或逗號(,)隔開,如果是邏輯或的關係,使用 || 隔開,邏輯與的優先級要高於邏輯或。
示例:
>=1.0
>=1.0 <2.0
>=1.0,<1.1 || >=1.2
帶連字符的版本範圍:-
- 如果是
X.Y的格式,即只有一位小數點,左閉右開。
示例:1.0 - 2.0,2.0 等於 2.0.*,即2.0後面可以為任意數字,即小於2.1,合併一起表示:>=1.0.0 < 2.1
- 如果是
X.Y.Z的格式,即有兩位小數點,左右皆閉合。
示例:1.0.0 - 2.1.0,表示:>=1.0.0 <=2.1.0
帶通配符的版本範圍:*
左閉右開
上面 2.0.* 就用到了通配符,即為:>=2.0 < 2.1
波浪線版本範圍:~
- 如果是
X.Y的格式,即只有一位小數點,最大兼容版本可上升到主版本(即整數部分)+1以下,左閉右開。
示例:~1.2 表示:>=1.2 <2.0.0,因為 1.2 只有一位小數,即可小於 2.0.0,此處的1表示主版本。
- 如果是
X.Y.Z的格式,即有兩位小數,最大兼容版本只能上升到次要版本(即第一個小數)+1以下,左閉右開。
示例:~1.2.3 表示:>=1.2.3 <1.3.0
插入符號版本範圍:^
- 如果整數部分和所有小數部分都大於0,則最大兼容版本可上升到主版本(即整數部分)+1以下,左閉右開。
示例:^1.2.3 表示:>=1.2.3 <2.0.0,主版本是1,所以可以小於 2.0.0
- 如果整數部分等於0,且第一個小數部分大於0,則最大兼容版本可上升到次要版本(即第一個小數)+1以下,左閉右開。
示例:^0.3 表示:>=0.3.0 <0.4.0,次要版本是第一個小數為3,所以可以小於 0.4.0
- 如果整數部分和第一個小數都等於0,則最大兼容版本可上升到第二個小數(即最後一個小數)+1以下,左閉右開。
示例:^0.0.3 表示:>=0.0.3 <0.0.4
版本約束後綴標誌解析
例如,後綴帶有:-stable, -dev。
明確指定後綴的,則應用後綴的標誌。
示例:
1.2.3:明確指定了版本,則內部表示為:1.2.3-stable>1.2:大於版本的範圍,則內部表示為:>1.2.0-stable>=1.2:大於等於版本的範圍,則內部表示為:>=1.2.0-dev>=1.2-stable:明確指定了-stable後綴的範圍,則內部表示為:>=1.2.0-stable<1.3:小於版本的範圍,則內部表示為:<1.3.0-dev<=1.3:小於等於版本的範圍,則內部表示為:<=1.3.0-stable1.0 - 2.0:連字符指定1到2的範圍,則內部表示為:>=1.0.0-dev < 2.1.0-dev~1.3:用波浪線操作符指定的範圍,則內部表示為:>=1.3.0-dev < 2.0.0-dev^1.2.3:用插入符號指定的範圍,則內部表示為:>=1.2.3-dev <2.0.0-dev1.4.*:用通配符指定的範圍,則內部表示為:>=1.4.0-dev <1.5.0-dev
九、怎麼驗證依賴包所需的版本?
有一個用愛發電的 Packagist Semver Checker 的網站提供了版本檢查驗證功能,只要提供依賴包版本,它會自動標識出有哪些版本的包可用。
如圖,提供依賴:madewithlove/htaccess-cli: ^1.3.0,則最大版本不超過2.0。
十、如何發佈包到Packagist上?
- 新建一個項目,或者已有項目,包含
composer.json文件,包含至少以下配置項:
{
// 包名必須存在
"name": "your-vendor-name/package-name",
// 描述信息必須存在
"description": "A short description of what your package does",
// 依賴項必須存在
"require": {
"php": ">=8.2",
"another-vendor/package": "1.*"
}
}
- 驗證
composer.json文件的語法格式是否正確
composer validate
- 提交代碼到
github或其他版本控制系統倉庫。 - 進入
packagist官方網站,創建賬號並登錄,點擊Submit按鈕。
- 在提交頁面填入倉庫地址,系統會定期自動抓取包。
十一、資源地址
- composer官方網站
- composer命令文檔
- composer.json文件結構解析文檔
- composer版本約束解析文檔
- packagist官方網站
- composer源碼地址
- Packagist Semver Checker源碼地址