本文來自pilishen.com----原文連接; 歡迎來和pilishen一塊兒學習php&Laravel;學習羣:109256050php
該篇屬於《Laravel底層核心技術實戰揭祕》這一課程《laravel底層核心概念解析》這一章的擴展閱讀。考慮到學員們的基礎差別,爲了不視頻當中過於詳細而連篇累牘,故將一些laravel底層實現相關的PHP知識點以文章形式呈現,供你們預習和隨時查閱。laravel
基本上,使用laravel pipelines你能夠將一個實例對象(object)在多個類之間傳遞,就像流水順着管道依次流淌通常,最終呢,層層傳遞,你就獲得了從頭到尾一系列執行操做的「最終」結果。數據庫
固然,laravel裏pipeline(管道、通道)相關的,最直接的例子就是Middleware了。藉助這種通道方式,Middleware能夠很方便地層層「過濾」(filter)進入你程序中的request。json
下面是一個基本的Middleware例子:bootstrap
<?php
namespace App\Http\Middleware;
use Closure;
class TestMiddleware
{
public function handle($request, Closure $next)
{
// 這裏添加本身的邏輯
return $next($request);
}
}
複製代碼
middleware就像是咱們的request請求流經的「管道」,這期間能夠執行必要的操做,好比判斷當前請求是一個http請求呢,仍是一個json請求呢,或者也能夠檢查一下用戶的權限,或許這個時候你就會想到咱們laratrust(或Entrust)插件一系列經典的Middleware。bash
在《Laravel底層核心技術實戰揭祕》課程裏,涉及到service provider的加載註冊原理和源碼解讀的時候,咱們一塊兒看過Illuminate\Foundation\Http\Kernel
這個class,期間呢詳細分析了sendRequestThroughRouter
這個方法:app
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
// 視頻裏咱們重點分析了啓動過程
$this->bootstrap();
// 下面的這個返回過程咱們沒有詳細展開
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
複製代碼
注意return
後面的那段,看字面意思都很好理解:ide
一個
new Pipeline
發送了(send)request請求,經過了(through)咱們的Middleware,而後(then)提交給了路由。函數
假設呢你在寫一個論壇功能,用戶呢能夠建立話題、評論話題,可是呢,你的客戶要求你實現一個能自動替換刪除某些內容、符號的功能,數據處理了之後呢才能寫入數據庫,好比說具體的需求列表是這樣的:post
*
極可能最後呢,你須要實現下面的這個處理過程:
$pipes = [
RemoveBadWords::class
ReplaceLinkTags::class
RemoveScriptTags::class
];
複製代碼
咱們須要的是,將須要處理的內容依次傳遞到這三個class中,上一個class的執行結果要傳給下一個class來繼續處理,那麼相似的需求,咱們就可使用pipeline
來實現:
<?php
public function create(Request $request)
{
$pipes = [
RemoveBadWords::class,
ReplaceLinkTags::clas,
RemoveScriptTags::class
];
$post = app(Pipeline::class)
->send($request->content)
->through($pipes)
->then(function ($content) {
return Post::create(['content' => 'content']);
});
// return any type of response
}
複製代碼
每個數據處理的class,都應該有一個handle
方法來執行具體的邏輯,因此這個時候讓它們都擴展或實現某個特定的interface比較好:
<?php
namespace App;
use Closure;
interface Pipe
{
public function handle($content, Closure $next);
}
複製代碼
而後呢假設咱們過濾敏感詞的class就能夠這樣寫:
<?php
namespace App;
use Closure;
class RemoveBadWords implements Pipe
{
public function handle($content, Closure $next)
{
//具體的替換邏輯,更新掉$content
return $next($content);
}
}
複製代碼
這裏handle方法接收兩個參數,第一個是你要在管道中傳遞的對象(passable object),第二個呢是一個Closure,也便是匿名函數,它指代你管道中的下一步,當前這一步的邏輯執行完了,就能夠把結果傳給下一步。
你也能夠不用handle
這個方法名,但這個時候你須要經過via
方法來指定自定義方法的名字:
app(Pipeline::class)
->send($content)
->through($pipes)
->via(‘customMethodName’) // <---- 在這兒指定
->then(function ($content) {
return Post::create(['content' => $content]);
});
複製代碼
原文出處://medium.com/@jeffochoa/understanding-laravel-pipelines-a7191f75c351