一、前言
本篇文章只適合入門的小白,請大佬們手下留情
很多同學在進行laravel
開發時,都會遇到開發重複功能的情況,比如:對於錯誤處理,每個公司有每個公司的標準,所以關於這一塊的處理是不一樣的,網上又沒有特定的包,而自己開發的時候每個專案的錯誤處理又是一樣的?怎麼辦?自己再把寫過的錯誤處理檔案再重新複製一份?這樣是不現實的,為什麼?就舉個很簡單的一個例子,比如你有10個專案,你的10個專案都用到了這個錯誤處理檔案,但是某一天,因為公司的業務調整,需要你修改了某個專案的檔案的錯誤處理,修改好了之後,你再一個專案一個專案的去複製過去,這樣也太繁瑣了。這時候你就需要一個統一的管理工具,那就是利用composer
工具開發一個laravel
包,只要修改了檔案,直接利用composer
更新就好了。
所以我打算寫一個簡單的儲存資訊的demo包,然後通過laravel
引入該包並且使用,類似效果如下:
輸入這些資訊提交之後,就會在資料庫增加一條資訊,如下:
二、準備
- 安裝好
composer
,會簡單的使用 - 準備好
git
,會簡單的使用 - 準備好
mysql
資料庫 - 熟悉
laravel6.x
文件 - 準備兩個
laravel6.x
框架.一個用來開發laravel
包,就叫做laravel-6.x-demo
;另一個用來使用開發出來的包,就叫做laravel-6.x-formal
。以上兩個框架請自己初始化配置,以下不再講
三、開發步驟
1. 利用composer初始化本地包
開啟
laravel-6.x-demo
專案,在該專案的app
的同級目錄建立package
,再在package
目錄下建立message
目錄在終端進入到剛建立的
message
目錄,執行composer init
,然後終端彈出如下圖的內容:
上面的內容分別是:包名(Package name)->描述(Description )->作者(Author)->穩定性(Minimum Stability [])->包型別(Package Type)->執照(License)->是否引入依賴外部包->是否引入依賴外部開發包->是否確認。
除了包名和作者名可以跟我的不一樣,其他都可以和我的一樣,或者按照自己的(符合composer的規則就行)想法也行
上面的操作做完之後會在
message
目錄底下多一個composer.json
檔案在
message
目錄下建立src
目錄,我們開發的原始碼檔案都放在這個目錄,現在結構如下圖所示:
2. 自動載入包
為了你開發的包能夠被框架識別需要在
composer.json
(注意:不是在package\message\composer.json
檔案的)的autoload-dev
加入如下語法:{ "autoload-dev": { "psr-4": { "Tests\\": "tests/", "DevPackage\\Message\\":"package/message/src/" } } }
然後在專案的根目錄下執行
composer dump-autoload
(注意:這裡的根目錄不是package\message\
目錄, 是專案目錄根目錄,下同).關於為什麼要進行上述操作請參閱:How to create a PSR-4 autoloader for my project?及composer官方文件自動載入
為了你釋出的包在其他
laravel
專案能夠自動載入(識別名稱空間),那麼必須在package\message\composer.json
,加入如下程式碼{ "autoload": { "psr-4": { "DevPackage\\Message\\": "src/" } } }
現在整體的
package\message\composer.json
檔案就變成了如下內容{ "name": "dp1/message", "description": "laravel", "type": "library", "license": "MIT", "authors": [ { "name": "xxx", "email": "xxx@163.com" } ], "minimum-stability": "dev", "require": {}, "autoload": { "psr-4": { "DevPackage\\Message\\": "src/" } } }
3. 載入擴充套件包的路由
在終端專案根目錄下使用
php artisan make:provider MessageServiceProvider
建立服務提供者,然後將MessageServiceProvider.php
檔案從app\Providers
目錄移動到package\message\src
目錄下,注意要修改該檔案名稱空間,內容如下<?php namespace DevPackage\Message; use Illuminate\Support\ServiceProvider; class MessageServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // } /** * Bootstrap services. * * @return void */ public function boot() { // } }
在配置檔案
config\app.php
的providers
註冊服務提供者,如下:DevPackage\Message\MessageServiceProvider::class
載入擴充套件包的路由
在
package\message\src\
目錄下建立擴充套件包的路由檔案routes\web.php
,web.php
內容如下:<?php use Illuminate\Support\Facades\Route; Route::get('message', function () { return "success"; });
然後在
MessageServiceProvider.php
的boot()
方法下加入如下程式碼,就可以載入路由了/** * Bootstrap services. * * @return void */ public function boot() { // 載入擴充套件包的路由檔案 $this->loadRoutesFrom(__DIR__.'/routes/web.php'); }
然後在終端根目錄下使用
php artisan serve
啟動服務,在網頁上訪問http://127.0.0.1:8000/message
,如果頁面出現success
就成功
4. 載入擴充套件包的檢視
在
package\message\src\
目錄下建立擴充套件包的檢視檔案views\message.php.html
,message.php.html
內容如下:<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="{{save}}" method="post"> @csrf 姓名:<input type="text" name="name" placeholder="請輸入你的名字"> 資訊: <input type="text" name="message" placeholder="請輸入資訊"> <input type="submit"> </form> </body> </html>
然後在
MessageServiceProvider.php
的boot()
方法下加入如下程式碼,就可以載入檢視了/** * Bootstrap services. * * @return void */ public function boot() { // 載入擴充套件包的路由檔案 $this->loadRoutesFrom(__DIR__.'/routes/web.php'); // 載入擴充套件包的檢視檔案 $this->loadViewsFrom(__DIR__.'/views', 'message'); }
修改
package\message\src\routes\web.php
檔案為了
web.php
檔案不放那麼多程式碼,在擴充套件包建立控制器Http\controllers\MessageController.php
,內容如下<?php namespace DevPackage\Message\Http\controllers; use App\Http\Controllers\Controller; use Illuminate\Http\Request; /** * * @author weirui * @date 2021-10-14 */ class MessageController extends Controller { public function index() { return view("message::message"); } public function save(Request $request) { } }
那麼
web.php
就可以修改為<?php use Illuminate\Support\Facades\Route; /** * * @author weirui * @date 2021-10-14 */ Route::group(['namespace' => 'DevPackage\Message\Http\controllers'], function () { Route::get('message',"MessageController@index")->name('message'); Route::post('message', "MessageController@save")->name('save'); });
在網頁上訪問http://127.0.0.1:8000/message
,出現如下頁面就表示成功
5. 載入擴充套件包資料庫遷移
在終端的專案根目錄執行
php artisan make:model Message -m
,建立message
模型和遷移檔案將模型檔案
message.php
從app
目錄移動到到擴充套件包的package\message\src\Models
目錄下,並且增加內容如下<?php namespace DevPackage\Message\Models; use Illuminate\Database\Eloquent\Model; class Message extends Model { // 黑名單 protected $guarded = []; }
將遷移檔案
2021_10_15_094100_create_messages_table.php
從database\migrations
目錄移動到擴充套件包的package\message\src\database\migrations
目錄下,增加內容如下<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateMessagesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('messages', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->string('message'); $table->string('config'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('messages'); } }
在
.env
配置資料庫相關資訊DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=dev_package DB_USERNAME=root DB_PASSWORD=root
然後在
MessageServiceProvider.php
的boot()
方法下加入如下程式碼,就可以載入資料庫遷移了/** * Bootstrap services. * * @return void */ public function boot() { // 載入擴充套件包的路由檔案 $this->loadRoutesFrom(__DIR__.'/routes/web.php'); // 載入擴充套件包的檢視檔案 $this->loadViewsFrom(__DIR__.'/views', 'message'); // 載入擴充套件包的資料庫遷移 $this->loadMigrationsFrom(__DIR__.'/database/migrations'); }
執行資料庫遷移命令
php artisan migrate
,就可以在資料庫看到message
這個表
6.載入擴充套件包的配置檔案
修改
package\message\src\Http\controllers\MessageController.php
的save()
方法public function save(Request $request) { $req = $request->all(); // 載入擴充套件包的配置檔案 $config = config('message.config'); $data = [ 'name' => $req['name'], 'message' => $req['message'], 'config' => $config ]; Message::create($data); return redirect(route('message')); }
載入擴充套件包的配置檔案
在擴充套件包
package\message\src\
建立config\message.php
,內容如下<?php return [ "config" => 123 ];
然後在
MessageServiceProvider.php
的boot()
方法下加入如下程式碼,就可以載入配置檔案了/** * Bootstrap services. * * @return void */ public function boot() { // 載入擴充套件包的路由檔案 $this->loadRoutesFrom(__DIR__.'/routes/web.php'); // 載入擴充套件包的檢視檔案 $this->loadViewsFrom(__DIR__.'/views', 'message'); // 載入擴充套件包的資料庫遷移 $this->loadMigrationsFrom(__DIR__.'/database/migrations'); // 載入擴充套件包的配置檔案 $this->mergeConfigFrom(__DIR__.'/config/message.php', 'message'); }
增加了配置檔案之後,記得要重新執行
php artisan serve
重新啟動服務,如果不這樣做,會出現資料庫連線不上的問題
提交之後可以看到資料表內容如下
看到欄位config
為123就表時成功了
7. 釋出到packagist
在
github
上新建一個倉庫,用來儲存我們開發的包,如下將我們開發的
package\message
包上傳到github
新建的倉庫中(請自行操作)將包上傳完了之後開啟packagist網頁,
登入
,然後點選下圖的Submit
在
Repository URL (Git/Svn/Hg)
輸入你剛上傳的包的github
的URL
,如下圖
- 點選
Check
,沒問題之後點選Submit
,就可以看到你的包以及釋出成功了。
8. 在專案中引進包
- 開啟
laravel-6.x-formal
專案,在根目錄下,使用composer require dp1/message
命令(這個命令的來源看下圖)引入你開發的包。
然後在
laravel-6.x-formal
專案的執行php artisan serve
,然後輸入http://127.0.0.1:8000/message
(記得要關閉laravel-6.x-demo
專案的服務),但是發現頁面上顯示404 not find
,這是為什麼呢?經過檢視官方文件,發現是自己在專案laravel-6.x-demo
的package\message\composer.json
忘記加入發現擴充套件包,那麼,加入如下程式碼"extra": { "laravel": { "providers": [ "DevPackage\\Message\\MessageServiceProvider" ] } }
然後提交到
github
,而packagist
需要等待一小會才會同步更新到然後在
laravel-6.x-formal
專案的執行composer remove dp1/message
移除包,然後再執行composer require dp1/message
引入包,再在終端輸入php artisan serve
啟動服務,最後再在瀏覽器輸入http://127.0.0.1:8000/message
就可以看到正常的頁面,說明成功了。在
laravel-6.x-formal
專案執行php artisan migrate
(請配置好資料庫連線),可以看到下載下來的擴充套件包的資料庫檔案已經建立,在瀏覽器上提交你輸入的資訊,也會儲存到資料庫9. 釋出群組檔案
進行群組檔案的釋出是為了你在引用某個包的時候可以自定義這個包裡面的內容,就比如,我想修改在
laravel-6.x-formal
專案修改我開發的擴充套件包dp1/messae
的配置檔案或者很醜的檢視檔案,那麼就要用到釋出群組檔案的功能。切換回專案
laravel-6.x-demo
,在package\message\src\MessageServiceProvider.php
的boot()
方法加入如下程式碼/** * Bootstrap services. * * @return void */ public function boot() { // 載入擴充套件包的路由檔案 $this->loadRoutesFrom(__DIR__.'/routes/web.php'); // 載入擴充套件包的檢視檔案 $this->loadViewsFrom(__DIR__.'/views', 'message'); // 載入擴充套件包的資料庫遷移 $this->loadMigrationsFrom(__DIR__.'/database/migrations'); // 載入擴充套件包的配置檔案 $this->mergeConfigFrom(__DIR__.'/config/message.php', 'message'); // 進行包釋出(命令:php artisan vendor:publish,然後選擇你的包) $this->publishes([ // 釋出配置檔案(釋出後的配置檔案會在/config目錄下) __DIR__ . '/config/message.php' => config_path('messasge.php'), // 帆布檢視檔案(釋出後的檢視檔案會在resource/views/vendor/message下) __DIR__ . '/views' => resource_path('views/vendor/message') ]); }
提交程式碼到github,打上版本號(自行操作),可以在
packagist
看到版本號,如下所示在專案
laravel-6.x-formal
中在終端使用命令composer require dp1/message:v1.0.0
更新dp1/message
包,然後在終端執行命令php artisan vendor/publish
,看到你引入的包並選擇,如下現在可以在專案
laravel-6.x-formal
看到config\message.php
檔案和resources\views\vendor\message\messag.blade.php
檔案,你可以在這兩個檔案自定義你要的內容,我在這裡不再演示
四、結尾
第一次寫文章,有寫的不好的,請大家多多見諒,也請大家多多指點。謝謝
本作品採用《CC 協議》,轉載必須註明作者和本文連結