Middleware.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: Slince <taosikai@yeah.net>
  10. // +----------------------------------------------------------------------
  11. namespace think;
  12. use InvalidArgumentException;
  13. use LogicException;
  14. use think\exception\HttpResponseException;
  15. class Middleware
  16. {
  17. protected $queue = [];
  18. protected $app;
  19. protected $config = [
  20. 'default_namespace' => 'app\\http\\middleware\\',
  21. ];
  22. public function __construct(App $app, array $config = [])
  23. {
  24. $this->app = $app;
  25. $this->config = array_merge($this->config, $config);
  26. }
  27. public static function __make(App $app, Config $config)
  28. {
  29. return new static($app, $config->pull('middleware'));
  30. }
  31. public function setConfig(array $config)
  32. {
  33. $this->config = array_merge($this->config, $config);
  34. }
  35. public function import(array $middlewares = [])
  36. {
  37. foreach ($middlewares as $middleware) {
  38. $this->add($middleware);
  39. }
  40. }
  41. /**
  42. * {@inheritdoc}
  43. */
  44. public function add($middleware)
  45. {
  46. if (is_null($middleware)) {
  47. return;
  48. }
  49. $middleware = $this->buildMiddleware($middleware);
  50. if ($middleware) {
  51. $this->queue[] = $middleware;
  52. }
  53. }
  54. /**
  55. * {@inheritdoc}
  56. */
  57. public function unshift($middleware)
  58. {
  59. if (is_null($middleware)) {
  60. return;
  61. }
  62. $middleware = $this->buildMiddleware($middleware);
  63. if ($middleware) {
  64. array_unshift($this->queue, $middleware);
  65. }
  66. }
  67. /**
  68. * {@inheritdoc}
  69. */
  70. public function all()
  71. {
  72. return $this->queue;
  73. }
  74. /**
  75. * {@inheritdoc}
  76. */
  77. public function dispatch(Request $request)
  78. {
  79. return call_user_func($this->resolve(), $request);
  80. }
  81. protected function buildMiddleware($middleware)
  82. {
  83. if (is_array($middleware)) {
  84. list($middleware, $param) = $middleware;
  85. }
  86. if ($middleware instanceof \Closure) {
  87. return [$middleware, isset($param) ? $param : null];
  88. }
  89. if (!is_string($middleware)) {
  90. throw new InvalidArgumentException('The middleware is invalid');
  91. }
  92. if (false === strpos($middleware, '\\')) {
  93. if (isset($this->config[$middleware])) {
  94. $middleware = $this->config[$middleware];
  95. } else {
  96. $middleware = $this->config['default_namespace'] . $middleware;
  97. }
  98. }
  99. if (is_array($middleware)) {
  100. return $this->import($middleware);
  101. }
  102. if (strpos($middleware, ':')) {
  103. list($middleware, $param) = explode(':', $middleware, 2);
  104. }
  105. return [[$this->app->make($middleware), 'handle'], isset($param) ? $param : null];
  106. }
  107. protected function resolve()
  108. {
  109. return function (Request $request) {
  110. $middleware = array_shift($this->queue);
  111. if (null === $middleware) {
  112. throw new InvalidArgumentException('The queue was exhausted, with no response returned');
  113. }
  114. list($call, $param) = $middleware;
  115. try {
  116. $response = call_user_func_array($call, [$request, $this->resolve(), $param]);
  117. } catch (HttpResponseException $exception) {
  118. $response = $exception->getResponse();
  119. }
  120. if (!$response instanceof Response) {
  121. throw new LogicException('The middleware must return Response instance');
  122. }
  123. return $response;
  124. };
  125. }
  126. }