基於 Composer 的 PHP 模組化開發

overtrue發表於2017-07-18

file

這個話題之前是在微博公司內部做的技術分享,這裡拿出來分享給大家。

基於 GitHub 或者其它平臺託管的開源專案的引入大家應該都已經非常熟悉了,但是公司內部專案的模組化應該怎麼做呢?這或許是不少朋友頭疼的問題。

file

我們先聊聊 PHP 模組化開發演進的過程,在沒有 GitHub 之前,我們大家獲取與分享程式碼的方式主要是部落格,國內的 CSDN 或者部落格園還有很多很多,大家都是從文章內複製到自己專案裡面使用。現在看起來真的是相當原始粗暴,但是那個時代也沒有太多可選的方案。導致的現象就是一段程式碼在 N 個專案裡出現,可能見得最多的就是獲取客戶端 IP 的那幾行了,在網際網路上不止出現了幾萬遍。現在很多專案裡都還是這段:

file

是不是很熟悉?

這種引入程式碼的方式有很多弊端:比如不安全,因為很多人是直接複製貼上就用上了,根本沒花時間去考證它是否真的是安全的。另外一個問題就是不同步,你今天在別人那裡複製過來就用上了,後來作者發現了 bug 並修復更新了文章也不會通知你,你也不可能記得這段程式碼來自哪裡去檢查更新。

file

在沒有 Composer 之前我們是如何引入程式碼的呢?除了上面說的複製貼上以外,在 PHP 中還有 pear,不過自從用過兩次我就再也不用它了,一種說不出來的感覺。

不信你可以找一些舊的專案看看,在沒有 Composer 之前的專案中,你會發現大量的重複程式碼,以及各種花樣的組織格式,各種規範的寫法。這也是 Composer 誕生的原因之一。

file

Composer 給我們帶來了諸多的好處:

  • 模組化,降低程式碼重用成本
  • 統一的第三方程式碼組織方式
  • 更科學的版本更新

這三個是比較重要的特徵了,基於 GitHub 的共享程式碼方式解決了傳統引入方式帶來了各種問題。

我們先來了解一點 Composer 基礎。

file

Composer 的實現結構相對比較簡單,Packagist.org 是 Composer 官方資料來源,它的資料基於 GitHub 等程式碼託管平臺,你在本地使用 Composer 命令列工具,基於 Packagist.org 的資料資訊安裝與更新依賴。 本地安裝 Composer 非常簡單,主要有以下幾種方式:

file

新手同學需要注意的是,這裡一定要確定 composer 安裝目錄在環境變數 $PATH 內才能全域性使用 composer 命令。

那接下來我們聊一下如何建立一個 Composer 包。

file

步驟很簡單,建立目錄,然後在目錄內使用命令 composer init 按照提示完成包的初始化。

接著就是完成你的程式碼編寫,然後在 composer.json 檔案配置你的引入方式等資訊。 然後我們如何對已經寫好的程式碼進行測試呢?

file

我們需要在其它任何地方建立一個測試專案(不要在剛才建立的包目錄就可以),比如這裡我們建立一個叫 'my-package-test' 的目錄,然後在目錄裡 composer init 完成專案初始化。接著就是宣告專案依賴,我們這裡要依賴的就是剛才建立好的包,由於我們的包還沒有釋出到 packagist,所以是無法直接 composer require 來安裝的,我們需要告訴 composer 從哪裡載入我們的包資訊:


    $ composer config repositories.foo path /Users/overtrue/www/foo/bar

我們通過這個命令在 composer.json 中 repositories 區塊新增了一個專案源。

然後我們新增包依賴:


    $ composer require foo/bar:dev-master -vvv

這樣就完成了包的安裝,你會發現這樣的安裝方式它只是建立了一個軟連結到包目錄,所以,你在測試的時候就可以直接在 vendor/foo/bar 下修改程式碼,這樣就加快了你的開發速度。

更多細節這裡你就自己去研究了,我們來看看 composer.json 檔案:

file

我們最需要關心的就是圖裡上面的三個部分了,包名、依賴、以及自動載入,是必不可少的部分。

剛才我們提到了包的安裝,安裝依賴包的方式主要有以下兩種:

file

手動方式是不太推薦的,容易寫錯,比如後面多一個逗號之類的,不過你可以寫完以後使用以下命令來驗證:


    $ composer validate

更新依賴就非常簡單了:

file

雖然在上一篇文章我們已經講了語言化版本,這裡再提一次:

file
file

我們在依賴一個包的時候,很多同學對於依賴的版本一直處於蒙逼狀態,那看完下一頁你就恍然大悟了,首先是兩個符號:"~" 與 "^"

file

接著是版本號的範圍的各種寫法:

file

還有包含穩定性的標識:

file

這裡需要說一下生產環境最重要也一直是好多同學不清楚的一個東西:版本鎖定,很多人在糾結,要不要把 composer.lock 上傳到程式碼庫啊。我可以給你一個特別簡單的判斷方法:

如果你的程式碼是一個專案,就上傳,如果是一個工具包,給大家用的,就別上傳。

file

在已經存在 composer.lock 的目錄執行 composer install 的時候,是不會分析包依賴的,它只是按 composer.lock 中描述的下載地址直接下載,所以會快很多,而且版本號是具體的。那怕包已經發了新版,只要 composer.lock 沒動過,它就會按 composer.lock 裡的版本來安裝。composer update 時會更新 composer.lock,所以不要亂用 composer update。

包開發好了怎麼釋出?開源的方式是這樣的:

file

最後一句請酌情考慮。

另外一種釋出方式是閉源,公司內部用的包,上傳到 GitLab 或者其它私有的程式碼託管平臺,有兩種玩法:

  1. 最容易的玩法,在 composer.json 中新增 repositories 直接用 vcs 指定程式碼庫地址

這樣做有一個缺點,當你的包很多的時候,你全都得在 composer.json 中加上才行。

  1. 自已架設 Packagist 類似的服務,Packagist 官方提供了兩款: Toran,收費,開源方案是 Satis,不過它偏手動一些,自己酌情選擇即可。

私有包有一個點需要注意:授權,私有包肯定都是需要授權才能訪問的,這裡由於方案不太通用,大家根據自己的場景來解決就好了。

另外,有一些痛點不曉得啥時候能夠解決:

file
file
file

好在 Laravel China 已經為了我提供了國內目前最穩定最好用的映象源,Composer 中文映象 / Packagist 中國全量映象正式釋出!

最後總結一下:

微信並不適合聊一些程式碼細節的東西,我更多的傾向於提供思路。

在 PHP 現代開發中,Composer 已經是離不開的東西了,它的確加快了我們的開發速度節省了開發成本,如果你還在糾結用不用 Composer,那你真得反思一下了。

本文標題是模組化開發,內容主要介紹了包的建立與測試,以及公有包與私有包的釋出方案。但是無法幫你解決,如何拆分專案這類問題,這得基於你的長期經驗積累,但是有一些經驗可以分享一下:

  1. 不要過度設計,很多自以為很 NB 我不把學到的東西用上就是不爽的同學,上來就分庫分表,uuid 做主鍵之類,專案運營了好幾年一個表還沒到100萬條記錄,也是夠厲害的。
  2. 不要過早設計,真正 NB 的架構是演進而來的,不是前期設計出來的,當然不是說完全不需要設計哈,恰當的根據實際情況來就好,不要立項就把“千萬”、“億級”、“百億” 這些單位掛在嘴邊,也許到你專案倒閉那天你都沒到過任何一個量級。隨著專案逐漸改進即可。
  3. 優先關注成本,很多同學以為是效能,No! 技術團隊真正的成本是人力,所以開發效率才是優先需要關注的。上次文章在發在知乎有人就強制把我的“不要首先關注效能”解讀成了“效能不重要”,也是夠厲害的,語文也許跟養殖場動物學的。數學正常一點的人都會算,一臺伺服器多少錢?一個技術員工多少錢?伺服器你花 20 萬是永久資產,一個員工 20 萬呢?半年工資?一年工資?

今天的內容就是這些,上次一哥們未經過我的授權就把文章給貼到今日頭條去了,如果你今天再看到,請不要再做這種小毛孩子的事情了。你起碼署個名啊...

求轉發到朋友圈,幫我早日開啟評論功能,愛你!

喜歡請關注:假裝我會寫程式碼

相關文章