本文主要包含幾個部分
- Composer倉庫講述
- 為什么要搭建私有的Composer倉庫
- 如何開發(fā)composer包
- satis搭建私有倉庫
- satis的UI界面重構(gòu)思路
- 參考文檔
一氯夷、Composer倉庫
- Composer
Composer是 PHP 用來管理依賴(dependency)關(guān)系的工具。你可以在自己的項目中聲明所依賴的外部工具庫(libraries),Composer 會幫你安裝這些依賴的庫文件
- Composer倉庫
Composer倉庫是用來管理以及存儲php拓展包的一個集合庇忌。如packagist.org.
- php拓展包的形式
- php底層語言編寫的:一般使用pecl安裝或采取源碼安裝方式争舞。
- php編寫的:一般可通過pear安裝 或 Composer安裝 或 手動引入
- 典型的例子:phpredis 與 predis
二、為什么要搭建私有的Composer倉庫
-
首先列舉幾個很熟悉的場景
- 在項目當(dāng)中不可避免的會用到一些常見的函數(shù)枷遂,比如說一個獲取客戶端ip的代碼樱衷。一般開發(fā)會選擇去百度、谷歌酒唉,然后一頓ctrl c + v ...接著就拷貝到各個項目當(dāng)中矩桂,跑起來能用,ok沒問題。但是過了一段時間侄榴,咦雹锣,原來這段代碼有一個bug。A項目改一下癞蚕、B項目也改一下蕊爵,C項目忘記改了...
- 在公司內(nèi)部的項目里,我們經(jīng)常會發(fā)現(xiàn)多個項目之間會存在一些公用的模塊桦山。如攒射,公司內(nèi)部有多個C端,但是都有一個統(tǒng)一的數(shù)據(jù)接口模塊恒水。那么多個項目之間都會寫重復(fù)調(diào)用這個模塊接口的代碼会放。我們可以在A項目中寫了,拷貝到B钉凌、C....咧最,但此時如果數(shù)據(jù)模塊接口發(fā)生了變化,那就...
- 公司項目之間御雕,前后端業(yè)務(wù)層甚至模型層矢沿,重復(fù)的代碼很多,但是用的框架都是一樣的...
- ...
-
上面說了這幾個場景酸纲,在實際的開發(fā)工作當(dāng)中很常見捣鲸,總結(jié)來說存在以下幾個問題:
- 代碼質(zhì)量角度:常用的函數(shù),重用的模塊代碼福青,大家習(xí)慣了拷貝摄狱,代碼質(zhì)量很自然的少關(guān)注
- 開發(fā)效率角度:項目之間應(yīng)用了重復(fù)的代碼,拷貝接入效率低 或者 根本就不知道其他項目中有存在的輪子
- 維護(hù)成本角度:重復(fù)的代碼使用,假如出現(xiàn)了bug或者需要迭代以適應(yīng)新的需求无午,需要在一個個項目中調(diào)整 甚至還可能出現(xiàn)忘記的情況
- 開源角度:在工作當(dāng)中媒役,我們所開發(fā)的很多東西是不方便開源的
ps:其實上面說了那么多,最迫切需要搭建私有倉庫的是最后一點...
- 針對上述的問題有幾個初步方案:
- 在packagist上發(fā)布包:開源不符合宪迟,私有需要付費
- 直接composer.json中通過聲明內(nèi)部vcs的 respository:符合酣衷,但管理不方便,查找不方便
- 搭建一個私有的Composer倉庫:符合次泽,需要花點時間搭建維護(hù)
- toran proxy:不開源穿仪,有便捷操作的UI界面
- satis:開源,有UI界面意荤,但是不是很方便操作啊片,需要美化一下
PS:pear包同樣也是php的包,但是已過時了玖像,composer正值壯年紫谷。
三、如何開發(fā)composer包
上面講了很多為什么要模塊化、為什么要做composer包笤昨、為什么要搭建私有composer倉庫祖驱,那么接下來我們首先看下怎么做一個自己的composer包以及回顧一下有哪些知識。
1.composer.json中一些常用的參數(shù)
- name
- 包名瞒窒,一般包含兩部分[vendor/name]捺僻。“/”前面代碼發(fā)行的一個單位或大板塊崇裁,后面的是包名字
- type
- 包的類型
- libray:拓展庫匕坯,默認(rèn)類型,最常用的(安裝完默認(rèn)會在root包中vendor目錄下寇壳,什么是root包下面再說)
- project:項目醒颖,比如說laravel等一些框架提供了一些出事話項目的命令 composer create-project ...(此時發(fā)包就是定義這種類型妻怎,安裝完就是一個root包)
- metapackage:當(dāng)一個空的包壳炎,包含依賴并且需要觸發(fā)依賴的安裝,這將不會對系統(tǒng)寫入額外的文件逼侦。因此這種安裝類型并不需要一個 dist 或 source(官方說明)
- composer-plugin:一個安裝類型為 composer-plugin 的包匿辩,它有一個自定義安裝類型,可以為其它包提供一個 installler榛丢。詳細(xì)請查看 自定義安裝類型(官方說明)
- 包的類型
- description
- 包的描述铲球,告訴別人這個包用來干嘛的
- license
- 包的許可協(xié)議
- authors
- 發(fā)行機(jī)構(gòu)(個人)信息
- repositories
- 自定義資源庫(默認(rèn)情況下,composer會按照順序進(jìn)行資源查找晰赞,最后才檢測默認(rèn)的資源庫)
- type:資源庫類型
- path:本地資源包(支持絕對路勁稼病、相對路徑)
- vcs:git、svn等版本控制的資源包
- composer:composer資源鏡像倉庫下的資源包掖鱼,如https://mirrors.aliyun.com/composer/然走、packagist.org
- package
- type:資源庫類型
- 自定義資源庫(默認(rèn)情況下,composer會按照順序進(jìn)行資源查找晰赞,最后才檢測默認(rèn)的資源庫)
- require
- 項目必須安裝的依賴包
- require-dev
- 項目開發(fā)或測試環(huán)境下需要安裝的依賴包
- autoload
- 自動加載映射定義,支持四種類型映射定義(在開發(fā)包時戏挡,可直接通過修改autoload配置進(jìn)行包的引入進(jìn)行調(diào)試)
- psr-0:支持psr-4命名空間到目錄的映射芍瑞、精確到文件的映射
- psr-4:支持psr-4命名空間到目錄的映射、精確到文件的映射
- classmap:支持指定路徑的文件映射掃描褐墅,也支持精確到文件
- files:指定加載文件拆檬,一般用于函數(shù)庫加載
- 自動加載映射定義,支持四種類型映射定義(在開發(fā)包時戏挡,可直接通過修改autoload配置進(jìn)行包的引入進(jìn)行調(diào)試)
- autoload-dev:
- 測試環(huán)境下使用的自動加載映射定義,同上支持四種類型映射定義
- scripts
- 自定義腳本(僅root包中運作妥凳。在composer運行的生命周期當(dāng)中觸發(fā)的一些鉤子腳本竟贯,跟git上面hook是一個道理。詳細(xì)的可到官方文檔中去查)
- config
- 配置項(composer的一些局部配置項逝钥,常用的比如composer config secure-http false)
- extra
- 額外的一些配置參數(shù)(配合scripts中使用)
2.composer的常用命令
-
composer install
- 說明:安裝包依賴以及自動加載映射相關(guān)文件屑那。存在composer.lock文件的情況下,此命令會按照composer.lock中鎖定的依賴包版本號等信息直接安裝,否則即按照composer.json中聲明的一來信息進(jìn)行安裝
- 常用可選參數(shù)
- --no-dev:忽略composer.json下聲明的require-dev包
- --dev:安裝composer.json下聲明的包
- --optimize-autoloader:將psr0/psr4規(guī)范下的自動加載轉(zhuǎn)化為classmap的方式
- --no-scripts:跳過 composer.json 文件中定義的腳本
- 應(yīng)用場景
- 一般用于項目初始化
-
composer update
- 說明:根據(jù)composer.json文件中的聲明進(jìn)行項目依賴更新齐莲、自動加載映射痢站。
- 常用可選參數(shù)
- --no-dev:忽略composer.json下聲明的require-dev包
- --dev:安裝composer.json下聲明的包
- --optimize-autoloader:將psr0/psr4規(guī)范下的自動加載轉(zhuǎn)化為classmap的方式
- --no-scripts:跳過 composer.json 文件中定義的腳本
- 應(yīng)用場景
- 特定的依賴包需要更新。==請謹(jǐn)慎直接使用composer update,這會導(dǎo)致所有依賴包升級至依賴的最高版本选酗,可能會對項目造成不可預(yù)估的損害==
-
composer require package_name[:version]:
- 說明:安裝新包
- 常用可選參數(shù):
- --dev: 安裝 require-dev 字段中列出的包阵难。
- --no-update: 禁用依賴關(guān)系的自動更新(在確保項目能運作的情況下,可使用此命令)
- 應(yīng)用場景:
- 引入新包
-
composer dumpautoload:
- 說明:重新生成各依賴包的自動加載映射文件
- 常用可選參數(shù):
- --optimize (-o): 轉(zhuǎn)換 PSR-0/4 autoloading 到 classmap 獲得更快的載入速度芒填。這特別適用于生產(chǎn)環(huán)境呜叫,但可能需要一些時間來運行,因此它目前不是默認(rèn)設(shè)置殿衰。
- --no-dev: 禁用 autoload-dev 規(guī)則朱庆。
-
常用的全局參數(shù)
- -v:表示正常輸出
- -vv:表示更詳細(xì)的輸出
- -vvv:debug級別的信息(一般裝包時候,卡住了闷祥,不知道什么原因娱颊,可以加上此命令看看)
//來個示例說明一下
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=7.0.0",
"barryvdh/laravel-debugbar": "^3.2",
"bkqw_tech/ucenter": "^2.0",
"encore/laravel-admin": "^1.6",
"fideloper/proxy": "~3.3",
"intervention/image": "^2.4",
"jacobcyl/ali-oss-storage": "^2.1",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"maatwebsite/excel": "~2.1.0",
"mrgoon/aliyun-sms": "dev-master",
"overtrue/laravel-wechat": "^4.0",
"predis/predis": "^1.1",
"simplesoftwareio/simple-qrcode": "^2.0",
"topthink/think-helper": "^1.0"
},
"require-dev": {
"filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "~1.0",
"phpunit/phpunit": "~6.0",
"symfony/thanks": "^1.0"
},
"autoload": {
"files": [
"app/Support/Helpers/common.php"
],
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
]
}
},
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true,
"secure-http": false
},
"repositories": {
"ucenter": {
"type": "composer",
"url": "http://10.1.11.88:7075/"
}
}
}
ps:大家可以了解一下vendor目錄下composer文件夾的大概結(jié)構(gòu),大概了解一下composer的原理凯砍。知道原理能讓我們做起來更加得心應(yīng)手箱硕。
3.初始化composer包
- 命令行初始化
- 手動創(chuàng)建composer.json文件
{ "name": "adam/composertest", "description": "這是一個測試包", "type": "library", "authors": [ { "name": "Adam", "email": "wangyi@163.com" } ], "require": {} }
包的結(jié)構(gòu)就不用多說了,只要符合幾種composer的自動加載機(jī)制就可以了悟衩,沒什么特別限制
4.發(fā)布包
這里說一下在packagist上發(fā)布一個包剧罩,下面再說搭自己的私有倉庫
1.先把自己的項目發(fā)布到vcs的一個托管平臺,如github座泳,gitee
2.注冊一個packagist賬號
3.進(jìn)入https://packagist.org惠昔,點擊submit,提交挑势,完事
就這么簡單镇防,關(guān)于包的版本管理,可以拓展研究一下
5.安裝包
直接composer require <package_name>:dev-master薛耻。這里說下composer安裝包的幾種方式聲明
(1).本地安裝聲明
{
"name": "adam/project",
"description": "這是一個測試包",
"type": "project",
"authors": [{
"name": "Adam",
"email": "wangyi@163.com"
}],
"require": {},
"repositories": {
"composertest": {
"type": "path",
"url": "packages1/composertest"http://相對路徑或絕對路徑
}
}
}
(2).vcs安裝聲明
{
"name": "adam/project",
"description": "這是一個測試項目",
"type": "project",
"authors": [{
"name": "Adam",
"email": "wangyi@163.com"
}],
"require": {},
"repositories": {
"easywechat": {
"type": "vcs",//vcs营罢、git、svn
"url": "https://github.com/w7corp/easywechat.git"http://遠(yuǎn)程版本倉庫地址
}
}
}
(3).composer安裝聲明
{
"name": "adam/project",
"description": "這是一個測試項目",
"type": "project",
"authors": [{
"name": "Adam",
"email": "wangyi@163.com"
}],
"require": {},
"repositories": {
"easywechat": {
"type": "composer",
"url": "https://packagist.org/"http://composer倉庫地址
}
}
}
(4).其他安裝方式聲明
{
"name": "adam/project",
"description": "這是一個測試項目",
"type": "project",
"authors": [{
"name": "Adam",
"email": "wangyi@163.com"
}],
"require": {},
"repositories": {
"easywechat": {
"type": "composer",
"url": "https://packagist.org/"http://composer倉庫地址
}
}
}
四饼齿、satis搭建私有倉庫
1.安裝satis
- git安裝:git clone https://github.com/composer/satis.git
- composer安裝:composer create-project composer/satis --stability=dev
2.配置公鑰
如果將要引入的依賴包是一個私有vcs項目饲漾,請務(wù)必進(jìn)行配置。如果你引入的包都是公有項目可以跳過此步驟(參考配置文檔:https://gitee.com/help/articles/4181)缕溉。
ssh-keygen -t rsa -C "xxxxx@xxxxx.com"
# Generating public/private rsa key pair...
cat ~/.ssh/rsa_id.pub
# 將公鑰復(fù)制到你的托管平臺ssh公鑰設(shè)置里面
3.初始化satis
- 在項目根目錄運行 php bin/build init
- 根據(jù)提示輸入自己的倉庫名以及原地址首頁(后續(xù)再webpage上可以看到安裝包的json展示的即homepage地址)
{
"name": "adam's composer repository",
"homepage": "http://composer.cc",
"repositories": [],
"require-all": true
}
4.構(gòu)建satis UI界面
(1) 構(gòu)建:
-
方式一:
- 修改satis.json文件
{ "name": "adam", "homepage": "https://adamoba.com", "repositories": [ { "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech/ucenter.git" } ], "require-all":true, "config":{ "secure-http":false } }
- 運行構(gòu)建命令
php bin/satis build --repository-url http://10.1.11.88:8024/bkqw_tech/ucenter.git satis.json ./web
-
方式二:
- 修改satis.json文件
{ "name": "adam", "homepage": "https://adamoba.com", "repositories": [ { "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech/ucenter.git" } ], "require":{ "bkqw_tech/ucenter":"*" }, "config":{ "secure-http":false } }
- 運行構(gòu)建命令
php bin/satis build --repository-url http://10.1.11.88:8024/bkqw_tech/ucenter.git satis.json ./web
如果源中包含了http協(xié)議考传,需增加secure-http為false的配置項
說明:
- 如果直接build,不加入repository-url或者不修改require-all參數(shù)的情況下证鸥,satis會掃描所有的respositories(包括composer的默認(rèn)源僚楞,不清楚原因),會導(dǎo)致構(gòu)建非常非常慢
- 如果加入了repository-url的情況下勤晚,satis只會掃描指定的vcs地址
(2)配置一個php運行環(huán)境,運行時目錄指向到web目錄下(示例域名:http://composer.cc)
(3) 訪問:http://composer.cc泉褐,看到如下界面赐写,即成功
4.發(fā)布包到satis
(1)修改配置文件:
- 命令行
php bin/satis add http://10.1.11.88:8024/bkqw_tech2/ucenter2.git
- 編輯配置文件:
{
"name": "adam",
"homepage": "https://adamoba.com",
"repositories": [
{ "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech/ucenter.git" },
{ "type": "vcs", "url": "http://10.1.11.88:8024/bkqw_tech2/ucenter2.git" }
],
"require-all":all
"config":{
"secure-http":false
}
}
(2) 構(gòu)建
- 命令行 php bin/satis build --repository-url http://10.1.11.88:8024/bkqw_tech2/ucenter2.git satis.json ./web
- 訪問:http://composer.cc
6.在項目中引入satis的包
//這一段即http://composer.cc種,add repositories那一段展開json
{
"repositories": [{
"type": "composer",
"url": "https://composer.cc"
}]
}
//或通過命令行進(jìn)行局部配置 composer config repositories.ucenter composer https://adamoba.com
{
"repositories": {
"ucenter":{
"type": "composer",
"url": "http://composer.cc"
}
}
}
// 因為此處repository的里面的包基本都是http協(xié)議膜赃,所以外加如一行
{
"config":{
"secure-http":false
}
}
// 或通過命令行 composer conifg secure-http false
// 接著composer require xxx
//(如果項目沒有打上標(biāo)簽挺邀,composer require package_name:dev-master)
關(guān)于satis命令如何使用,直接在運行php bin/satis 就可以查看到相關(guān)的說明了跳座。
五端铛、satis改造:可視化操作添加源
如果公司內(nèi)部成員都會發(fā)布一些包到這個satis站點里面,讓大家都去熟悉satis可能不那么理想疲眷。那接下來就通過對satis項目的進(jìn)行一些調(diào)整禾蚕,以達(dá)到可視化操作添加源的目的(如packagist.com中,只需要貼入地址就可以狂丝,提交一個源到其中過了)
- 思路
- 打開satis目錄下的views文件夾换淆,找到index.html.twig(這個是satis首頁的模板)
- 增加前端頁面:
- 每一個包的item增加刪除按鈕、更新按鈕
- 增加發(fā)布新包頁面(為了便捷美侦,我拷貝了一下packagis.com的頁面)
- 增加后端處理腳本:
- 刪除包:通過php的exec函數(shù)調(diào)用 “php bin/satis purge xxxx”产舞,再php調(diào)用satis build
- 更新包:通過php的exec函數(shù)執(zhí)行“php bin/satis build --respository-url=url_name satis.json ./web pacakage_name”
- 增加包:通過php的exec函數(shù)執(zhí)行“php bin/satis add --respository-url=url_name --type=vcs --name=package_name”,最后執(zhí)行更新包的命令
另外的思路實現(xiàn)vcs包添加與更新:以gitlab為例菠剩,配置gitlab的webhook,在每次接收到新推送時耻煤,觸發(fā)對應(yīng)的satis url具壮,檢測到包存在則執(zhí)行更新命令,包不存在則執(zhí)行新增命令
六哈蝇、參考文檔
- 基于 Composer 的 PHP 模塊化開發(fā)
- 正確的 Composer 擴(kuò)展包安裝方法
- composer.json的基礎(chǔ)架構(gòu)
- composer命令行的使用
- satis簡介