laravel 中间件 管道

╰+哭是因爲堅強的太久メ 2021-10-23 10:39 423阅读 0赞

管道模式 是将复杂的处理流程分解成多个独立的子任务

Laravel中的管道体现在中间件中,主要是通过 array_reduce这个函数来实现的

  1. <?php
  2. $arr = [1,2,3];
  3. $r = array_reduce($arr,'sum');
  4. function sum($carry,$pipe){
  5. $carry += $pipe;
  6. return $carry;
  7. }
  8. var_dump($r) //输出6

array_reduce() 这个函数可以 回调函数循环的作用到每个元素中,从而将数组简化成单一的值

demo:

  1. <?php
  2. interface RequestInterface
  3. {
  4. public static function handel(Closure $next);
  5. }
  6. class Request1 implements RequestInterface
  7. {
  8. public static function handel(Closure $next){
  9. echo "Request1 Begin." . "<br />";
  10. $next();
  11. echo "Request1 End." . "<br />";
  12. }
  13. }
  14. class Request2 implements RequestInterface
  15. {
  16. public static function handel(Closure $next){
  17. echo "Request2 Begin." . "<br />";
  18. $next();
  19. echo "Request2 End." . "<br />";
  20. }
  21. }
  22. class Request3 implements RequestInterface
  23. {
  24. public static function handel(Closure $next){
  25. echo "Request3 Begin." . "<br />";
  26. $next();
  27. echo "Request3 End." . "<br />";
  28. }
  29. }
  30. class Request4 implements RequestInterface
  31. {
  32. public static function handel(Closure $next){
  33. echo "Request4 Begin." . "<br />";
  34. $next();
  35. echo "Request4 End." . "<br />";
  36. }
  37. }
  38. class Client
  39. {
  40. private $pipes = [
  41. 'Request1',
  42. 'Request2',
  43. 'Request3',
  44. 'Request4',
  45. ];
  46. private function defaultClosure()
  47. {
  48. return function(){
  49. echo '请求处理中...' . "<br />";
  50. };
  51. }
  52. //整个请求处理管道的关键
  53. private function getSlice(){
  54. return function($stack,$pipe){
  55. return function()use($stack,$pipe){
  56. return $pipe::handel($stack);
  57. };
  58. };
  59. }
  60. //负责发起请求处理
  61. public function then(){
  62. call_user_func(array_reduce($this->pipes, $this->getSlice(),$this->defaultClosure()));
  63. }
  64. }
  65. $worker = new Client();
  66. $worker->then();

第一次运行:

$stack = $this->defaultClosure() 是一个回调函数 function(){ echo ‘请求处理中…’ . “
“;} 作为 getSlice() 第一个参数 假设为s1

最终返回的是一个回调函数

function(s1,’Request1’){

  1. return function()use(s1,'Request1')\{
  2. return Request1::handel(s1);

}

}

假设该匿名函数为s2

第二次运行:

得到回调函数

function(s2,’Request2’){

  1. return function()use(s2,'Request2')\{
  2. return Request2::handel(s2);

}

}

假设该回调函数为s3

第三次运行

得到回调函数

function(s3,’Request3’){

  1. return function()use(s3,'Request3')\{
  2. return Request3::handel(s3);

}

}

假设该回调函数为s4

第四次运行

得到回调函数

function(s4,’Request4’){

  1. return function()use(s4,'Request4')\{
  2. return Request4::handel(s4);

}

}

假设为s5

array_reduce() 返回一个回调函数 s5 然后 call_user_func(s5) 执行这个回调函数

先运行Request4::handel(s4) 输出Request4 Begin 再运行 $next() 也就是 执行s4()

Request3::handel(s3) 输出Request3Begin 再运行$next() 也就是执行s3()

Request2::handel(s2) 输出Request2Begin 再运行$next() 也就是执行s2()

Request1::handel(s1) 输出Request1Begin 再运行$next() 也就是执行s1()

$this->defaultClosure() 输出请求处理中…

接着继续输出

Request1 End.

Request2 End.

Request3 End.

Request4 End.

关系像这样

  1. function (){
  2. return Request4::handle(function (){
  3. return Request3::handle(function (){
  4. return Request2::handle(function (){
  5. return Reuqest1::handle(function (){
  6. echo '请求处理中...' . "<br />";
  7. });
  8. });
  9. });
  10. });
  11. }

执行上面代码后 返回

Request4 Begin.
Request3 Begin.
Request2 Begin.
Request1 Begin.
请求处理中…
Request1 End.
Request2 End.
Request3 End.
Request4 End.

发表评论

表情:
评论列表 (有 0 条评论,423人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Laravel中间实现原理

    1. 什么是中间件? 对于一个Web应用来说,在一个请求真正处理前,我们可能会对请求做各种各样的判断,然后才可以让它继续传递到更深层次中。而如果我们用if else这样子

    相关 Laravel管道技术

    什么是管道 所谓管道(Pipeline)设计模式就是将会数据传递到一个任务序列中,管道扮演者流水线的角色,数据在这里被处理然后传递到下一个步骤。 为什么使用管道 使用管道

    相关 Laravel 5.5 的中间

    简介 Laravel 的中间件提供了一种方便的机制来过滤进入应用的 HTTP 请求。例如,Laravel 内置了一个中间件来验证用户的身份认证。如果用户没有通过身份认证,