当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP Pipeline 实现中间件的示例代码

发布:smiling 来源: PHP粉丝网  添加日期:2022-03-03 09:16:23 浏览: 评论:0 

这篇文章主要介绍了PHP Pipeline 实现中间件的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

Pipeline 设计模式

水管太长,只要有一处破了,就会漏水了,而且不利于复杂环境弯曲转折使用,所以我们都会把水管分成很短的一节一节管道,然后最大化的让管道大小作用不同,因地制宜,组装在一起,满足各种各样的不同需求。

由此得出 Pipeline 的设计模式,就是将复杂冗长的流程 (processes) 截成各个小流程,小任务。每个最小量化的任务就可以复用,通过组装不同的小任务,构成复杂多样的流程 (processes)。

最后将「输入」引入管道,根据每个小任务对输入进行操作 (加工、过滤),最后输出满足需要的结果。

你可以拿koa的中间件机制来做参考,也就是我们常说的削洋葱思路

在前端里早期有一个工程打包工具gulp写法就更能体现pipeline

  1. gulp.task('css'function(){ 
  2.  return gulp.src('client/templates/*.less'
  3.   .pipe(less()) 
  4.   .pipe(minifyCSS()) 
  5.   .pipe(gulp.dest('build/css')) 
  6. }); 
  7.  
  8. gulp.task('js'function(){ 
  9.  return gulp.src('client/javascript/*.js'
  10.   .pipe(sourcemaps.init()) 
  11.   .pipe(concat('app.min.js')) 
  12.   .pipe(sourcemaps.write()) 
  13.   .pipe(gulp.dest('build/js')) 
  14. }); 
  15.  
  16. gulp.task('default', [ 'html''css''js' ]); 
  17. IlluminatePipeline 

Laravel 框架中的中间件,就是利用 Illuminate\Pipeline 来实现的,本来想写写我对 「Laravel 中间件」源码的解读,但发现网上已经有很多帖子都有表述了,所以本文就简单说说如何使用 Illuminate\Pipeline。

  1. public function demo(Request $request
  2.   $pipe1 = function ($payload, Closure $next) { 
  3.     $payload = $payload + 1; 
  4.     return $next($payload); 
  5.   }; 
  6.  
  7.   $pipe2 = function ($payload, Closure $next) { 
  8.     $payload = $payload * 3; 
  9.     return $next($payload); 
  10.   }; 
  11.  
  12.   $data = $request->input('data', 0); 
  13.  
  14.   $pipeline = new Pipeline(); 
  15.  
  16.   return $pipeline 
  17.     ->send($data
  18.     ->through([$pipe1$pipe2]) 
  19.     ->then(function ($data) { 
  20.       return $data
  21.     }); 

今天主要学习学习「Pipeline」,顺便推荐一个 PHP 插件:league/pipeline。

composer require league/pipeline

使用起来也很方便

  1. use League\Pipeline\Pipeline; 
  2.  
  3. class TimesTwoStage 
  4.   public function __invoke($payload
  5.   { 
  6.     return $payload * 2; 
  7.   } 
  8.  
  9. class AddOneStage 
  10.   public function __invoke($payload
  11.   { 
  12.     return $payload + 1; 
  13.   } 
  14.  
  15. $pipeline = (new Pipeline) 
  16.   ->pipe(new TimesTwoStage) 
  17.   ->pipe(new AddOneStage); 
  18.  
  19. // Returns 21 
  20. $pipeline->process(10); 

接下来我们添加FastRouter在我的项目中使用。

上面的代码修改成这样

我们接下来看看 RespondJson 里做了什么.

  1. <?php 
  2. namespace Platapps\Middlewares; 
  3. class RespondJson 
  4.   public function __invoke($payload
  5.   { 
  6.     header('Content-type:text/json'); 
  7.     return $payload
  8.   } 

就简单的加了个 header

我们试试把注释到一个渠道

我们再次访问的时候就变成

当然这是很简单的中间件,这种中间件远远不够,这里是核心代码,可以去这里看看,也比较简单。

我们最终需要修改pipe这个方法

  1. namespace League\Pipeline; 
  2.  
  3. class Pipeline implements PipelineInterface 
  4.   /** 
  5.    * @var callable[] 
  6.    */ 
  7.   private $stages = []; 
  8.  
  9.   /** 
  10.    * @var ProcessorInterface 
  11.    */ 
  12.   private $processor
  13.  
  14.   public function __construct(ProcessorInterface $processor = null, callable ...$stages
  15.   { 
  16.     $this->processor = $processor ?? new FingersCrossedProcessor; 
  17.     $this->stages = $stages
  18.   } 
  19.  
  20.   public function pipe(callable $stage): PipelineInterface 
  21.   { 
  22.     $pipeline = clone $this
  23.     $pipeline->stages[] = $stage
  24.  
  25.     return $pipeline
  26.   } 
  27.  
  28.   public function process($payload
  29.   { 
  30.     return $this->processor->process($payload, ...$this->stages); 
  31.   } 
  32.  
  33.   public function __invoke($payload
  34.   { 
  35.     return $this->process($payload); 
  36.   } 

这么多框架里面我这里建议拿Tp6的来做参考,功能还算够用。

  1. <?php 
  2. // +---------------------------------------------------------------------- 
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ] 
  4. // +---------------------------------------------------------------------- 
  5. // | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved. 
  6. // +---------------------------------------------------------------------- 
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) 
  8. // +---------------------------------------------------------------------- 
  9. // | Author: yunwuxin <448901948@qq.com> 
  10. // +---------------------------------------------------------------------- 
  11. namespace think; 
  12.  
  13. use Closure; 
  14. use Exception; 
  15. use Throwable; 
  16.  
  17. class Pipeline 
  18.   protected $passable
  19.  
  20.   protected $pipes = []; 
  21.  
  22.   protected $exceptionHandler
  23.  
  24.   /** 
  25.    * 初始数据 
  26.    * @param $passable 
  27.    * @return $this 
  28.    */ 
  29.   public function send($passable
  30.   { 
  31.     $this->passable = $passable
  32.     return $this
  33.   } 
  34.  
  35.   /** 
  36.    * 调用栈 
  37.    * @param $pipes 
  38.    * @return $this 
  39.    */ 
  40.   public function through($pipes
  41.   { 
  42.     $this->pipes = is_array($pipes) ? $pipes : func_get_args(); 
  43.     return $this
  44.   } 
  45.  
  46.   /** 
  47.    * 执行 
  48.    * @param Closure $destination 
  49.    * @return mixed 
  50.    */ 
  51.   public function then(Closure $destination
  52.   { 
  53.     $pipeline = array_reduce
  54.       array_reverse($this->pipes), 
  55.       $this->carry(), 
  56.       function ($passableuse ($destination) { 
  57.         try { 
  58.           return $destination($passable); 
  59.         } catch (Throwable | Exception $e) { 
  60.           return $this->handleException($passable$e); 
  61.         } 
  62.       }); 
  63.  
  64.     return $pipeline($this->passable); 
  65.   } 
  66.  
  67.   /** 
  68.    * 设置异常处理器 
  69.    * @param callable $handler 
  70.    * @return $this 
  71.    */ 
  72.   public function whenException($handler
  73.   { 
  74.     $this->exceptionHandler = $handler
  75.     return $this
  76.   } 
  77.  
  78.   protected function carry() 
  79.   { 
  80.     return function ($stack$pipe) { 
  81.       return function ($passableuse ($stack$pipe) { 
  82.         try { 
  83.           return $pipe($passable$stack); 
  84.         } catch (Throwable | Exception $e) { 
  85.           return $this->handleException($passable$e); 
  86.         } 
  87.       }; 
  88.     }; 
  89.   } 
  90.  
  91.   /** 
  92.    * 异常处理 
  93.    * @param $passable 
  94.    * @param $e 
  95.    * @return mixed 
  96.    */ 
  97.   protected function handleException($passable, Throwable $e
  98.   { 
  99.     if ($this->exceptionHandler) { 
  100.       return call_user_func($this->exceptionHandler, $passable$e); 
  101.     } 
  102.     throw $e
  103.   } 

这种写法有什么好?

其实就好就好在,你在处理一个请求的过程中,分配任务的时候,在处理的过程,每个中间的人,只要做自己处理的请求和结果还有请求即可,让当数据到达Controller里的时候,显示业务逻辑的时候更加强大

Tags: Pipeline PHP中间件

分享到: