Pipeline.php 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. namespace addons\shopro\library;
  3. use Closure;
  4. use Exception;
  5. use Throwable;
  6. class Pipeline
  7. {
  8. protected $passable;
  9. protected $pipes = [];
  10. protected $exceptionHandler;
  11. /**
  12. * 初始数据
  13. * @param $passable
  14. * @return $this
  15. */
  16. public function send($passable)
  17. {
  18. $this->passable = $passable;
  19. return $this;
  20. }
  21. /**
  22. * 调用栈
  23. * @param $pipes
  24. * @return $this
  25. */
  26. public function through($pipes)
  27. {
  28. $this->pipes = is_array($pipes) ? $pipes : func_get_args();
  29. return $this;
  30. }
  31. /**
  32. * 执行
  33. * @param Closure $destination
  34. * @return mixed
  35. */
  36. public function then(Closure $destination)
  37. {
  38. $pipeline = array_reduce(
  39. array_reverse($this->pipes),
  40. $this->carry(),
  41. function ($passable) use ($destination) {
  42. try {
  43. return $destination($passable);
  44. } catch (Throwable | Exception $e) {
  45. return $this->handleException($passable, $e);
  46. }
  47. }
  48. );
  49. return $pipeline($this->passable);
  50. }
  51. /**
  52. * 设置异常处理器
  53. * @param callable $handler
  54. * @return $this
  55. */
  56. public function whenException($handler)
  57. {
  58. $this->exceptionHandler = $handler;
  59. return $this;
  60. }
  61. protected function carry()
  62. {
  63. return function ($stack, $pipe) {
  64. return function ($passable) use ($stack, $pipe) {
  65. try {
  66. return $pipe($passable, $stack);
  67. } catch (Throwable | Exception $e) {
  68. return $this->handleException($passable, $e);
  69. }
  70. };
  71. };
  72. }
  73. /**
  74. * 异常处理
  75. * @param $passable
  76. * @param $e
  77. * @return mixed
  78. */
  79. protected function handleException($passable, Throwable $e)
  80. {
  81. if ($this->exceptionHandler) {
  82. return call_user_func($this->exceptionHandler, $passable, $e);
  83. }
  84. throw $e;
  85. }
  86. }