本文參考超哥寫的 基於 Composer 的 PHP 模塊化開發 的詳細實踐版。php
開發痛點html
我相信不少人,對 composer 不瞭解,在開發包的時候會這樣作:laravel
建立項目(jcc/new-package) -> 寫業務邏輯 -> push 到代碼倉庫 -> 建立調試項目 -> 安裝包(composer require jcc/new-package -vvv) -> 調試 -> 修改項目 -> push 更新代碼 -> 在調試項目中更新包代碼 (composer update -vvv) -> ...
因而可知,不斷重複的提交代碼,更新代碼,很是的麻煩,並且不能實時調試。git
本文主要解決的問題:
本地開發包時,可本地測試,不需將代碼提交到第三方代碼倉庫,再 composer require 安裝到項目中測試:github
建立項目(jcc/new-package) -> 寫業務邏輯 -> 建立調試項目 -> 配置 composer.json -> 調試 -> 修改項目 -> 直接在調試項目調試 -> ...
因而可知,本地開發可減小 git 提交拉取代碼的時間,下降了提交的每個版本儘量出現的低級錯誤。web
本地包開發的工做原理:
Composer 將本地開發的包經過軟鏈接的方式,重新項目( jcc/taxi )軟鏈接到調試項目( jcc/test-taxi/vendor/jcc/texi )shell
主要用到了 repositories 的 path 類型,更新信息請移步 文檔json
首先咱們看一下 Composer 安裝包的結構,正常使用的狀況下,拿一個安裝好 laravel/laravel)爲例子,打開 vendor 目錄下的 laravel 會看到如下的結構:app
vendor/laravel ├── framework │ └── src │ └── Illuminate │ └── ... └── tinker └── src └── Console
同時看一下 Laravel 項目下的 composer.json 文件的 require 或 require-dev 的依賴包:composer
{ ..., "require": { "php": ">=7.0.0", "fideloper/proxy": "~3.3", "laravel/framework": "5.5.*", "laravel/tinker": "~1.0" }, ... }
由此能夠知道目錄結構是對應關係的。
固然在初始化建立目錄的時候,要注意項目名跟目錄結構一致,例如個人新項目叫 jcc/taxi 那麼我建立的目錄結構應該這樣子:
jcc └── taxi
接着咱們須要在 taxi 下進來進一步的開發,固然,在開發前須要先初始化 composer 配置,在 taxi 目錄下運行:
composer init
按照指示填寫信息便可:
在 texi 目錄下會多出 composer.json 文件:
{ "name": "jcc/taxi", "description": "This is a test.", "type": "library", "license": "MIT", "authors": [ { "name": "jcc", "email": "changejian@gmail.com" } ], "minimum-stability": "dev", "require": {} }
通常狀況下,咱們會建立 2 個目錄,一個是 src 用於存放包全部的邏輯代碼,一個是 tests 用於存放測試用例:
jcc/taxi ├── src ├── tests ├── README.md ├── composer.json └── LICENSE
要注意的是,咱們須要再 composer.json 設置一下 composer 自動加載配置,在 composer.json 加入:
{ ..., "autoload": { "psr-4": { "Jcc\\Taxi\\": "src/" } }, "autoload-dev": { "psr-4": { "Jcc\\Taxi\\Tests\\": "tests/" } }, ... }
更多能夠看一下 Composer 自動加載文檔
首先,在 jcc 目錄下建立一個新的項目,用於測試:
jcc ├── taxi └── test-taxi
接着初始化 composer 配置,生成 composer.json 文件:
composer init
而後添加 Repositories 項目,有兩種方式:
第一種:直接運行命令
composer config repositories.jcc path /Users/jiajianchan/Sites/jcc/taxi
第二種:直接在 composer.json 文件添加:
{ ..., "repositories": { "jcc": { "type": "path", "url": "/Users/jiajianchan/Sites/jcc/taxi" } } }
type 類型爲 path,url 爲項目的相對路徑.
接下來就是添加依賴,一樣有兩種方式:
Shell:
composer require jcc/taxi:dev-master -vvv
composer.json 中添加:
{ ..., "require": { "jcc/taxi": "dev-master" }, ... }
固然要注意版本號,必須在 jcc/taxi 項目中的 composer.json 中設置
minimum-stability
屬性,否則在安裝包的時候會報找不到版本號的錯。
首先在 jcc/taxi 項目下的 src 中建立 Client.php 文件:
<?php namespace Jcc\Taxi; class Client { protected $a; protected $b; public function __construct(int $a, int $b) { $this->a = $a; $this->b = $b; } public function addTogether() { return $this->a + $this->b; } }
在 jcc/test-taxi 目錄下安裝一下 jcc/taxi 項目後,添加 test.php 文件:
// 引入 composer 自動加載文件 require __DIR__ . '/vendor/autoload.php' $client = new Jcc\Taxi\Client(5, 1); echo $client->addTogether() . "\n";
最後,在 jcc/test-taxi 目錄下運行 test.php 文件,便可得出相加的結果:
php test.php
若是你細心點,會發現,jcc/test-taxi 的 vendor 目錄下的 jcc/taxi
依賴項目是一個 軟鏈接
。也就是說,你在 jcc/taxi 中的 Client.php
文件添加一個新方法,而後在 jcc/test-taxi 項目中調用便可,不須要從新 composer update 包哦。很是方便。
本地開發一個 Laravel 包作法基本與 Composer 包開發同樣,簡單過一下吧。
首先建立一個新的 Laravel 項目:
composer create-project laravel/laravel laravel -vvv
在 Laravel 項目中建立以下目錄:
laravel ├── app ├── ... └── packages └── jcc └── taxi ├── LICENSE ├── README.md ├── composer.json ├── src │ ├── Taxi.php │ └── TaxiServiceProvider.php └── tests
jcc/taxi (vendor/name)
爲咱們要發佈的 Laravel 包,jcc
對應爲github username
,taxi
對應爲項目名
。
首先初始化 composer 配置,這個跟正常包開發沒區別,而後在 jcc/taxi 下的 src
目錄建立 TaxiServiceProvider.php
文件:
<?php namespace Jcc\Taxi; use Illuminate\Support\ServiceProvider; class TaxiServiceProvider extends ServiceProvider { public function boot() { // } public function register() { $this->app->singleton('taxi', function () { return new Taxi; }); } }
建立 Taxi.php
文件:
<?php namespace Jcc\Taxi; class Taxi { public function printRunning() { echo 'running' . "\n"; } }
最後就是想包註冊到 laravel 項目中,在 config/app.php
添加:
return [ ..., 'providers' => [ ..., Jcc\Taxi\TaxiServiceProvider::Class, ], ];
修改 laravel 項目下的 composer.json
文件:
{ ..., "autoload": { ..., "psr-4": { ..., "Jcc\\Taxi\\": "packages/jcc/taxi/src/" } }, ... }
並運行命令:
composer dump-autoload
最後在 web.php
中修改一下:
Route::get('/', function () { app('taxi')->printRunning(); });
此時,咱們訪問 laravel 項目的主頁時,會顯示 running
這個單詞,則恭喜你,成功了。
開發一個包說難不難,說易也不易,最重要的是你須要有源源不斷的創造力!