本文来自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