Passed
Push — 5.2 ( c6dbca...184417 )
by
unknown
02:35
created

Http::getRoutePath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
1 ignored issue
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
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: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think;
14
15
use think\exception\ClassNotFoundException;
16
use think\exception\HttpResponseException;
17
use think\route\Dispatch;
18
19
/**
20
 * Web应用管理类
21
 */
5 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
22
class Http
23
{
24
25
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
26
     * @var App
27
     */
28
    protected $app;
29
30
    /**
31
     * 是否需要使用路由
32
     * @var bool
33
     */
34
    protected $withRoute = true;
35
36
    /**
37
     * 访问控制器层名称
38
     * @var string
39
     */
40
    protected $controllerLayer = 'controller';
41
42
    /**
43
     * 是否使用控制器类库后缀
44
     * @var bool
45
     */
46
    protected $controllerSuffix = false;
47
48
    /**
49
     * 空控制器名称
50
     * @var string
51
     */
52
    protected $emptyController = 'Error';
53
54
    public function __construct(App $app)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
55
    {
56
        $this->app = $app;
57
    }
58
59
    /**
60
     * 设置是否使用路由
61
     * @access public
62
     * @param  bool $route
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
63
     * @return $this
64
     */
65
    public function withRoute(bool $route)
66
    {
67
        $this->withRoute = $route;
68
        return $this;
69
    }
70
71
    /**
72
     * 设置控制器层名称
73
     * @access public
74
     * @param  string $layer 控制器层名称
75
     * @return $this
76
     */
77
    public function controllerLayer(string $layer)
78
    {
79
        $this->controllerLayer = $layer;
80
        return $this;
81
    }
82
83
    /**
84
     * 设置空控制器名称
85
     * @access public
86
     * @param  string $empty 空控制器名称
87
     * @return $this
88
     */
89
    public function emptyController(string $empty)
90
    {
91
        $this->emptyController = $empty;
92
        return $this;
93
    }
94
95
    /**
96
     * 设置是否启用控制器类库后缀
97
     * @access public
98
     * @param  bool $suffix 启用控制器类库后缀
99
     * @return $this
100
     */
101
    public function controllerSuffix(bool $suffix = true)
102
    {
103
        $this->controllerSuffix = $suffix;
104
        return $this;
105
    }
106
107
    /**
108
     * 是否启用控制器类库后缀
109
     * @access public
110
     * @return bool
111
     */
112
    public function hasControllerSuffix(): bool
113
    {
114
        return $this->controllerSuffix;
115
    }
116
117
    /**
118
     * 获取控制器层名称
119
     * @access public
120
     * @return string
121
     */
122
    public function getControllerLayer(): string
123
    {
124
        return $this->controllerLayer;
125
    }
126
127
    /**
128
     * 执行应用程序
129
     * @access public
130
     * @return Response
131
     */
132
    public function run(): Response
133
    {
134
        try {
135
            if ($this->withRoute) {
136
                $dispatch = $this->routeCheck()->init();
137
            } else {
138
                $dispatch = $this->app->route->url($this->getRealPath())->init();
139
            }
140
141
            // 监听AppBegin
142
            $this->app->event->trigger('AppBegin');
143
144
            $data = null;
145
        } catch (HttpResponseException $exception) {
146
            $dispatch = null;
147
            $data     = $exception->getResponse();
148
        }
149
150
        $this->app->middleware->add(function (Request $request, $next) use ($dispatch, $data) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

150
        $this->app->middleware->add(function (/** @scrutinizer ignore-unused */ Request $request, $next) use ($dispatch, $data) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $next is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

150
        $this->app->middleware->add(function (Request $request, /** @scrutinizer ignore-unused */ $next) use ($dispatch, $data) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
151
            return is_null($data) ? $dispatch->run() : $data;
152
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
153
154
        $response = $this->app->middleware->dispatch($this->app->request);
155
156
        // 监听AppEnd
157
        $this->app->event->trigger('AppEnd', $response);
158
159
        return $response;
160
    }
161
162
    /**
163
     * 实例化访问控制器
164
     * @access public
165
     * @param  string $name 资源地址
166
     * @return object
167
     * @throws ClassNotFoundException
168
     */
169
    public function controller(string $name)
170
    {
171
        $suffix = $this->controllerSuffix ? 'Controller' : '';
172
        $class  = $this->app->parseClass($this->controllerLayer, $name . $suffix);
173
174
        if (class_exists($class)) {
175
            return $this->app->make($class, [], true);
176
        } elseif ($this->emptyController && class_exists($emptyClass = $this->app->parseClass($this->controllerLayer, $this->emptyController . $suffix))) {
177
            return $this->app->make($emptyClass, [], true);
178
        }
179
180
        throw new ClassNotFoundException('class not exists:' . $class, $class);
181
    }
182
183
    /**
184
     * 路由初始化(路由规则注册)
185
     * @access protected
186
     * @return void
187
     */
188
    protected function routeInit(): void
189
    {
190
        // 加载路由定义
191
        if (is_dir($this->getRoutePath())) {
192
            $files = glob($this->getRoutePath() . DIRECTORY_SEPARATOR . '*.php');
193
            foreach ($files as $file) {
194
                include $file;
195
            }
196
        }
197
198
        if ($this->app->route->config('route_annotation')) {
199
            // 自动生成注解路由定义
200
            if ($this->app->isDebug()) {
201
                $this->app->build->buildRoute();
202
            }
203
204
            $filename = $this->app->getRuntimePath() . 'build_route.php';
205
206
            if (is_file($filename)) {
207
                include $filename;
208
            }
209
        }
210
    }
211
212
    /**
213
     * URL路由检测(根据PATH_INFO)
214
     * @access protected
215
     * @return Dispatch
216
     */
217
    protected function routeCheck(): Dispatch
218
    {
219
        // 检测路由缓存
220
        if (!$this->app->isDebug() && $this->app->route->config('route_check_cache')) {
221
            $routeKey = $this->getRouteCacheKey();
222
            $option   = $this->app->route->config('route_cache_option');
223
224
            if ($option && $this->app->cache->connect($option)->has($routeKey)) {
225
                return $this->app->cache->connect($option)->get($routeKey);
226
            } elseif ($this->app->cache->has($routeKey)) {
227
                return $this->app->cache->get($routeKey);
228
            }
229
        }
230
231
        $this->routeInit();
232
233
        // 路由检测
234
        $dispatch = $this->app->route->check($this->getRealPath());
235
236
        if (!empty($routeKey)) {
237
            try {
238
                if (!empty($option)) {
239
                    $this->app->cache->connect($option)->tag('route_cache')->set($routeKey, $dispatch);
240
                } else {
241
                    $this->app->cache->tag('route_cache')->set($routeKey, $dispatch);
242
                }
243
            } catch (\Exception $e) {
244
                // 存在闭包的时候缓存无效
245
            }
246
        }
247
248
        return $dispatch;
249
    }
250
251
    /**
252
     * 获取路由缓存Key
253
     * @access protected
254
     * @return string
255
     */
256
    protected function getRouteCacheKey(): string
257
    {
258
        if ($this->app->route->config('route_check_cache_key')) {
259
            $closure  = $this->app->route->config('route_check_cache_key');
260
            $routeKey = $closure($this->app->request);
261
        } else {
262
            $routeKey = md5($this->app->request->baseUrl(true) . ':' . $this->app->request->method());
263
        }
264
265
        return $routeKey;
266
    }
267
268
    /**
269
     * 获取自动多应用模式下的实际URL Path
270
     * @access public
271
     * @return string
272
     */
273
    protected function getRealPath(): string
274
    {
275
        $path = $this->app->request->path();
276
277
        if ($path && $this->app->isAutoMulti()) {
278
            $path = substr_replace($path, '', 0, strpos($path, '/') ? strpos($path, '/') + 1 : strlen($path));
279
        }
280
281
        return $path;
282
    }
283
284
    /**
285
     * 获取路由目录
286
     * @access public
287
     * @return string
288
     */
289
    public function getRoutePath(): string
290
    {
291
        if ($this->app->isMulti()) {
292
            return $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . $this->app->getName() . DIRECTORY_SEPARATOR;
293
        }
294
295
        return $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR;
296
    }
297
298
}
299