Passed
Push — 5.2 ( 682159...5ca4d5 )
by liu
02:25
created

Http::path()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
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\HttpException;
16
17
/**
18
 * Web应用管理类
19
 */
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...
20
class Http
21
{
22
23
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
24
     * @var App
25
     */
26
    protected $app;
27
28
    /**
29
     * 应用路径
30
     * @var string
31
     */
32
    protected $path;
33
34
    /**
35
     * 是否多应用模式
36
     * @var bool
37
     */
38
    protected $multi = false;
39
40
    /**
41
     * 是否域名绑定应用
42
     * @var bool
43
     */
44
    protected $bindDomain = false;
45
46
    /**
47
     * 应用名称
48
     * @var string
49
     */
50
    protected $name;
51
52
    public function __construct(App $app)
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
53
    {
54
        $this->app   = $app;
55
        $this->multi = is_dir($this->app->getBasePath() . 'controller') ? false : true;
56
    }
57
58
    /**
59
     * 是否域名绑定应用
60
     * @access public
61
     * @return bool
62
     */
63
    public function isBindDomain(): bool
64
    {
65
        return $this->bindDomain;
66
    }
67
68
    /**
69
     * 设置应用模式
70
     * @access public
71
     * @param bool $multi
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
72
     * @return $this
73
     */
74
    public function multi(bool $multi)
75
    {
76
        $this->multi = $multi;
77
        return $this;
78
    }
79
80
    /**
81
     * 是否为多应用模式
82
     * @access public
83
     * @return bool
84
     */
85
    public function isMulti(): bool
86
    {
87
        return $this->multi;
88
    }
89
90
    /**
91
     * 设置应用名称
92
     * @access public
93
     * @param string $name 应用名称
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
94
     * @return $this
95
     */
96
    public function name(string $name)
97
    {
98
        $this->name = $name;
99
        return $this;
100
    }
101
102
    /**
103
     * 获取应用名称
104
     * @access public
105
     * @return string
106
     */
107
    public function getName(): string
108
    {
109
        return $this->name ?: '';
110
    }
111
112
    /**
113
     * 设置应用目录
114
     * @access public
115
     * @param string $path 应用目录
1 ignored issue
show
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
116
     * @return $this
117
     */
118
    public function path(string $path)
119
    {
120
        $this->path = $path;
121
        return $this;
122
    }
123
124
    /**
125
     * 执行应用程序
126
     * @access public
127
     * @param Request|null $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
128
     * @return Response
129
     */
130
    public function run(Request $request = null): Response
131
    {
132
        //自动创建request对象
133
        $request = $request ?? $this->app->make('request', [], true);
134
        $this->app->instance('request', $request);
135
136
        try {
137
            $response = $this->runWithRequest($request);
138
        } catch (\Throwable $e) {
139
            $this->reportException($e);
140
141
            $response = $this->renderException($request, $e);
142
        }
143
144
        return $response;
145
    }
146
147
    /**
148
     * 执行应用程序
149
     * @param Request $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
150
     * @return mixed
151
     */
152
    protected function runWithRequest(Request $request)
153
    {
154
        $this->app->initialize();
155
156
        if ($this->multi) {
157
            $this->parseMultiApp();
158
        }
159
160
        $withRoute = $this->app->config->get('app.with_route') ? function () {
161
            $this->loadRoutes();
162
        } : null;
163
164
        return $this->app->route->dispatch($request, $withRoute);
165
    }
166
167
    /**
168
     * 加载路由
169
     * @access protected
170
     * @return void
171
     */
172
    protected function loadRoutes(): void
173
    {
174
        // 加载路由定义
175
        if (is_dir($this->getRoutePath())) {
176
            $files = glob($this->getRoutePath() . DIRECTORY_SEPARATOR . '*.php');
177
            foreach ($files as $file) {
178
                include $file;
179
            }
180
        }
181
182
        if ($this->app->route->config('route_annotation')) {
183
            // 自动生成注解路由定义
184
            if ($this->app->isDebug()) {
185
                $this->app->build->buildRoute();
186
            }
187
188
            $filename = $this->app->getRuntimePath() . 'build_route.php';
189
190
            if (is_file($filename)) {
191
                include $filename;
192
            }
193
        }
194
    }
195
196
    /**
197
     * 获取路由目录
198
     * @access protected
199
     * @return string
200
     */
201
    protected function getRoutePath(): string
202
    {
203
        return $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . ($this->isMulti() ? $this->getName() . DIRECTORY_SEPARATOR : '');
204
    }
205
206
    /**
207
     * Report the exception to the exception handler.
208
     *
209
     * @param \Throwable $e
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
210
     * @return void
211
     */
212
    protected function reportException(\Throwable $e)
213
    {
214
        $this->app['error_handle']->report($e);
215
    }
216
217
    /**
218
     * Render the exception to a response.
219
     *
220
     * @param Request    $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
221
     * @param \Throwable $e
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value indented incorrectly; expected 2 spaces but found 1
Loading history...
222
     * @return Response
223
     */
224
    protected function renderException($request, \Throwable $e)
225
    {
226
        return $this->app['error_handle']->render($request, $e);
227
    }
228
229
    /**
230
     * 获取当前运行入口名称
231
     * @access protected
232
     * @return string
233
     */
234
    protected function getScriptName(): string
235
    {
236
        if (isset($_SERVER['SCRIPT_FILENAME'])) {
237
            $file = $_SERVER['SCRIPT_FILENAME'];
238
        } elseif (isset($_SERVER['argv'][0])) {
239
            $file = realpath($_SERVER['argv'][0]);
240
        }
241
242
        return isset($file) ? pathinfo($file, PATHINFO_FILENAME) : '';
243
    }
244
245
    /**
246
     * 解析多应用
247
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
248
    protected function parseMultiApp(): void
249
    {
250
        if ($this->app->config->get('app.auto_multi_app', false)) {
251
            // 自动多应用识别
252
            $this->bindDomain = false;
253
254
            $bind = $this->app->config->get('app.domain_bind', []);
255
256
            if (!empty($bind)) {
257
                // 获取当前子域名
258
                $subDomain = $this->app->request->subDomain();
259
                $domain    = $this->app->request->host();
260
261
                if (isset($bind[$domain])) {
262
                    $appName          = $bind[$domain];
263
                    $this->bindDomain = true;
264
                } elseif (isset($bind[$subDomain])) {
265
                    $appName          = $bind[$subDomain];
266
                    $this->bindDomain = true;
267
                }
268
            }
269
270
            if (!$this->bindDomain) {
271
                $map  = $this->app->config->get('app.app_map', []);
272
                $path = $this->app->request->pathinfo();
273
                $name = current(explode('/', $path));
274
275
                if (isset($map[$name])) {
276
                    if ($map[$name] instanceof \Closure) {
277
                        call_user_func_array($map[$name], [$this->app]);
278
                    } else {
279
                        $appName = $map[$name];
280
                    }
281
                } elseif ($name && false !== array_search($name, $map)) {
282
                    throw new HttpException(404, 'app not exists:' . $name);
283
                } else {
284
                    $appName = $name;
285
                }
286
287
                if ($name) {
288
                    $this->app->request->setRoot($name);
289
                    $this->app->request->setPathinfo(strpos($path, '/') ? ltrim(strstr($path, '/'), '/') : '');
290
                }
291
            }
292
        } else {
293
            $appName = $this->name ?: $this->getScriptName();
294
        }
295
296
        $this->loadApp($appName ?: $this->app->config->get('app.default_app', 'index'));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $appName does not seem to be defined for all execution paths leading up to this point.
Loading history...
Bug introduced by
It seems like $appName ?: $this->app->....default_app', 'index') can also be of type array and array; however, parameter $appName of think\Http::loadApp() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

296
        $this->loadApp(/** @scrutinizer ignore-type */ $appName ?: $this->app->config->get('app.default_app', 'index'));
Loading history...
297
    }
298
299
    protected function loadApp(string $appName): void
0 ignored issues
show
Coding Style introduced by
Missing function doc comment
Loading history...
300
    {
301
        $this->name = $appName;
302
        $this->app->request->setApp($appName);
303
        $this->app->setAppPath($this->path ?: $this->app->getBasePath() . $appName . DIRECTORY_SEPARATOR);
304
        $this->app->setRuntimePath($this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . $appName . DIRECTORY_SEPARATOR);
305
306
        //加载app文件
307
        if (is_file($this->app->getRuntimePath() . 'init.php')) {
308
            //直接加载缓存
309
            include $this->app->getRuntimePath() . 'init.php';
310
        } else {
311
            $appPath = $this->app->getAppPath();
312
313
            if (is_file($appPath . 'common.php')) {
314
                include_once $appPath . 'common.php';
315
            }
316
317
            $configPath = $this->app->getConfigPath();
318
319
            $files = [];
320
321
            if (is_dir($appPath . 'config')) {
322
                $files = array_merge($files, glob($appPath . 'config' . DIRECTORY_SEPARATOR . '*' . $this->app->getConfigExt()));
323
            } elseif (is_dir($configPath . $appName)) {
324
                $files = array_merge($files, glob($configPath . $appName . DIRECTORY_SEPARATOR . '*' . $this->app->getConfigExt()));
325
            }
326
327
            foreach ($files as $file) {
328
                $this->app->config->load($file, pathinfo($file, PATHINFO_FILENAME));
329
            }
330
331
            if (is_file($appPath . 'event.php')) {
332
                $this->app->loadEvent(include $appPath . 'event.php');
333
            }
334
335
            if (is_file($appPath . 'middleware.php')) {
336
                $this->app->middleware->import(include $appPath . 'middleware.php');
337
            }
338
339
            if (is_file($appPath . 'provider.php')) {
340
                $this->app->bind(include $appPath . 'provider.php');
341
            }
342
        }
343
344
        $this->app->setNamespace($this->app->config->get('app.app_namespace') ?: $this->app->getRootNamespace() . '\\' . $appName);
0 ignored issues
show
Bug introduced by
It seems like $this->app->config->get(...pace() . '\' . $appName can also be of type array; however, parameter $namespace of think\App::setNamespace() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

344
        $this->app->setNamespace(/** @scrutinizer ignore-type */ $this->app->config->get('app.app_namespace') ?: $this->app->getRootNamespace() . '\\' . $appName);
Loading history...
345
    }
346
}
347