本文参考超哥写的 基于 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
这个单词,则恭喜你,成功了。
开发一个包说难不难,说易也不易,最重要的是你须要有源源不断的创造力!