Completed
Push — 6.0 ( a46922...a4d0a5 )
by liu
06:54 queued 03:44
created

Http::__debugInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 7
ccs 0
cts 5
cp 0
crap 2
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 Closure;
16
use think\exception\Handle;
17
use think\exception\HttpException;
18
use Throwable;
19
20
/**
21
 * Web应用管理类
22
 */
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...
23
class Http
24
{
25
26
    /**
0 ignored issues
show
Coding Style introduced by
Missing short description in doc comment
Loading history...
27
     * @var App
28
     */
29
    protected $app;
30
31
    /**
32
     * 应用路径
33
     * @var string
34
     */
35
    protected $path;
36
37
    /**
38
     * 是否多应用模式
39
     * @var bool
40
     */
41
    protected $multi = false;
42
43
    /**
44
     * 是否域名绑定应用
45
     * @var bool
46
     */
47
    protected $bindDomain = false;
48
49
    /**
50
     * 应用名称
51
     * @var string
52
     */
53
    protected $name;
54
55 9
    public function __construct(App $app)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
56
    {
57 9
        $this->app   = $app;
58 9
        $this->multi = is_dir($this->app->getBasePath() . 'controller') ? false : true;
59 9
    }
60
61
    /**
62
     * 是否域名绑定应用
63
     * @access public
64
     * @return bool
65
     */
66 2
    public function isBindDomain(): bool
67
    {
68 2
        return $this->bindDomain;
69
    }
70
71
    /**
72
     * 设置应用模式
73
     * @access public
74
     * @param bool $multi
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
75
     * @return $this
76
     */
77 1
    public function multi(bool $multi)
78
    {
79 1
        $this->multi = $multi;
80 1
        return $this;
81
    }
82
83
    /**
84
     * 是否为多应用模式
85
     * @access public
86
     * @return bool
87
     */
88 7
    public function isMulti(): bool
89
    {
90 7
        return $this->multi;
91
    }
92
93
    /**
94
     * 设置应用名称
95
     * @access public
96
     * @param string $name 应用名称
1 ignored issue
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
97
     * @return $this
98
     */
99 1
    public function name(string $name)
100
    {
101 1
        $this->name = $name;
102 1
        return $this;
103
    }
104
105
    /**
106
     * 获取应用名称
107
     * @access public
108
     * @return string
109
     */
110 5
    public function getName(): string
111
    {
112 5
        return $this->name ?: '';
113
    }
114
115
    /**
116
     * 设置应用目录
117
     * @access public
118
     * @param string $path 应用目录
1 ignored issue
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
119
     * @return $this
120
     */
121 1
    public function path(string $path)
122
    {
123 1
        if (substr($path, -1) != DIRECTORY_SEPARATOR) {
124 1
            $path .= DIRECTORY_SEPARATOR;
125
        }
126
127 1
        $this->path = $path;
128 1
        return $this;
129
    }
130
131
    /**
132
     * 执行应用程序
133
     * @access public
134
     * @param Request|null $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
135
     * @return Response
136
     */
137 8
    public function run(Request $request = null): Response
138
    {
139
        //自动创建request对象
140 8
        $request = $request ?? $this->app->make('request', [], true);
141 8
        $this->app->instance('request', $request);
142
143
        try {
144 8
            $response = $this->runWithRequest($request);
145 2
        } catch (Throwable $e) {
146 2
            $this->reportException($e);
147
148 2
            $response = $this->renderException($request, $e);
149
        }
150
151 8
        return $response->setCookie($this->app->cookie);
152
    }
153
154
    /**
155
     * 初始化
156
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
157 7
    protected function initialize()
158
    {
159 7
        if (!$this->app->initialized()) {
160 7
            $this->app->initialize();
161
        }
162 7
    }
163
164
    /**
165
     * 执行应用程序
166
     * @param Request $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
167
     * @return mixed
168
     */
169 7
    protected function runWithRequest(Request $request)
170
    {
171 7
        $this->initialize();
172
173
        // 加载全局中间件
174 7
        if (is_file($this->app->getBasePath() . 'middleware.php')) {
175 7
            $this->app->middleware->import(include $this->app->getBasePath() . 'middleware.php');
176
        }
177
178 7
        if ($this->multi) {
179 6
            $this->parseMultiApp();
180
        }
181
182
        // 设置开启事件机制
183 6
        $this->app->event->withEvent($this->app->config->get('app.with_event', true));
0 ignored issues
show
Bug introduced by
It seems like $this->app->config->get('app.with_event', true) can also be of type array; however, parameter $event of think\Event::withEvent() does only seem to accept boolean, 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

183
        $this->app->event->withEvent(/** @scrutinizer ignore-type */ $this->app->config->get('app.with_event', true));
Loading history...
184
185
        // 监听HttpRun
186 6
        $this->app->event->trigger('HttpRun');
187
188
        $withRoute = $this->app->config->get('app.with_route', true) ? function () {
189 6
            $this->loadRoutes();
190 6
        } : null;
191
192 6
        return $this->app->route->dispatch($request, $withRoute);
193
    }
194
195
    /**
196
     * 加载路由
197
     * @access protected
198
     * @return void
199
     */
200 6
    protected function loadRoutes(): void
201
    {
202
        // 加载路由定义
203 6
        if (is_dir($this->getRoutePath())) {
204 1
            $files = glob($this->getRoutePath() . '*.php');
205 1
            foreach ($files as $file) {
206
                include $file;
207
            }
208
        }
209
210 6
        if ($this->app->route->config('route_annotation')) {
211
            // 自动生成注解路由定义
212 6
            if ($this->app->isDebug()) {
213
                $this->app->console->call('route:build', [$this->name]);
214
            }
215
216 6
            $filename = $this->app->getRuntimePath() . 'build_route.php';
217
218 6
            if (is_file($filename)) {
219
                include $filename;
220
            }
221
        }
222 6
    }
223
224
    /**
225
     * 获取路由目录
226
     * @access protected
227
     * @return string
228
     */
229 6
    protected function getRoutePath(): string
230
    {
231 6
        return $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR . ($this->isMulti() ? $this->getName() . DIRECTORY_SEPARATOR : '');
232
    }
233
234
    /**
235
     * Report the exception to the exception handler.
236
     *
237
     * @param Throwable $e
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
238
     * @return void
239
     */
240 1
    protected function reportException(Throwable $e)
241
    {
242 1
        $this->app->make(Handle::class)->report($e);
243 1
    }
244
245
    /**
246
     * Render the exception to a response.
247
     *
248
     * @param Request   $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
249
     * @param Throwable $e
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
250
     * @return Response
251
     */
252 1
    protected function renderException($request, Throwable $e)
253
    {
254 1
        return $this->app->make(Handle::class)->render($request, $e);
255
    }
256
257
    /**
258
     * 获取当前运行入口名称
259
     * @access protected
1 ignored issue
show
Coding Style introduced by
Tag value for @access tag indented incorrectly; expected 13 spaces but found 1
Loading history...
260
     * @codeCoverageIgnore
261
     * @return string
1 ignored issue
show
Coding Style introduced by
Tag value for @return tag indented incorrectly; expected 13 spaces but found 1
Loading history...
262
     */
263
    protected function getScriptName(): string
264
    {
265
        if (isset($_SERVER['SCRIPT_FILENAME'])) {
266
            $file = $_SERVER['SCRIPT_FILENAME'];
267
        } elseif (isset($_SERVER['argv'][0])) {
268
            $file = realpath($_SERVER['argv'][0]);
269
        }
270
271
        return isset($file) ? pathinfo($file, PATHINFO_FILENAME) : '';
272
    }
273
274
    /**
275
     * 解析多应用
276
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
277 6
    protected function parseMultiApp(): void
278
    {
279 6
        if ($this->app->config->get('app.auto_multi_app', false)) {
280
            // 自动多应用识别
281 5
            $this->bindDomain = false;
282
283 5
            $bind = $this->app->config->get('app.domain_bind', []);
284
285 5
            if (!empty($bind)) {
286
                // 获取当前子域名
287 5
                $subDomain = $this->app->request->subDomain();
288 5
                $domain    = $this->app->request->host(true);
289
290 5
                if (isset($bind[$domain])) {
291 1
                    $appName          = $bind[$domain];
292 1
                    $this->bindDomain = true;
293 4
                } elseif (isset($bind[$subDomain])) {
294 1
                    $appName          = $bind[$subDomain];
295 1
                    $this->bindDomain = true;
296 3
                } elseif (isset($bind['*'])) {
297
                    $appName          = $bind['*'];
298
                    $this->bindDomain = true;
299
                }
300
            }
301
302 5
            if (!$this->bindDomain) {
303 3
                $map  = $this->app->config->get('app.app_map', []);
304 3
                $deny = $this->app->config->get('app.deny_app_list', []);
305 3
                $path = $this->app->request->pathinfo();
306 3
                $name = current(explode('/', $path));
307
308 3
                if (isset($map[$name])) {
309 1
                    if ($map[$name] instanceof Closure) {
310
                        $result  = call_user_func_array($map[$name], [$this]);
311
                        $appName = $result ?: $name;
312
                    } else {
313 1
                        $appName = $map[$name];
314
                    }
315 2
                } elseif ($name && (false !== array_search($name, $map) || in_array($name, $deny))) {
316 1
                    throw new HttpException(404, 'app not exists:' . $name);
317 1
                } elseif ($name && isset($map['*'])) {
318
                    $appName = $map['*'];
319
                } else {
320 1
                    $appName = $name;
321
                }
322
323 2
                if ($name) {
324 2
                    $this->app->request->setRoot('/' . $name);
325 4
                    $this->app->request->setPathinfo(strpos($path, '/') ? ltrim(strstr($path, '/'), '/') : '');
326
                }
327
            }
328
        } else {
329 1
            $appName = $this->name ?: $this->getScriptName();
330
        }
331
332 5
        $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; 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

332
        $this->loadApp(/** @scrutinizer ignore-type */ $appName ?: $this->app->config->get('app.default_app', 'index'));
Loading history...
333 5
    }
334
335
    /**
336
     * 加载应用文件
337
     * @param string $appName 应用名
1 ignored issue
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
338
     * @return void
339
     */
340 5
    protected function loadApp(string $appName): void
341
    {
342 5
        $this->name = $appName;
343 5
        $this->app->request->setApp($appName);
344 5
        $this->app->setAppPath($this->path ?: $this->app->getBasePath() . $appName . DIRECTORY_SEPARATOR);
345 5
        $this->app->setRuntimePath($this->app->getRootPath() . 'runtime' . DIRECTORY_SEPARATOR . $appName . DIRECTORY_SEPARATOR);
346
347
        //加载app文件
348 5
        if (is_dir($this->app->getAppPath())) {
349 1
            $appPath = $this->app->getAppPath();
350
351 1
            if (is_file($appPath . 'common.php')) {
352 1
                include_once $appPath . 'common.php';
353
            }
354
355 1
            $configPath = $this->app->getConfigPath();
356
357 1
            $files = [];
358
359 1
            if (is_dir($configPath . $appName)) {
360 1
                $files = array_merge($files, glob($configPath . $appName . DIRECTORY_SEPARATOR . '*' . $this->app->getConfigExt()));
0 ignored issues
show
Bug introduced by
It seems like glob($configPath . $appN...s->app->getConfigExt()) can also be of type false; however, parameter $array2 of array_merge() does only seem to accept array|null, 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

360
                $files = array_merge($files, /** @scrutinizer ignore-type */ glob($configPath . $appName . DIRECTORY_SEPARATOR . '*' . $this->app->getConfigExt()));
Loading history...
361
            } elseif (is_dir($appPath . 'config')) {
362
                $files = array_merge($files, glob($appPath . 'config' . DIRECTORY_SEPARATOR . '*' . $this->app->getConfigExt()));
363
            }
364
365 1
            foreach ($files as $file) {
366
                $this->app->config->load($file, pathinfo($file, PATHINFO_FILENAME));
367
            }
368
369 1
            if (is_file($appPath . 'event.php')) {
370 1
                $this->app->loadEvent(include $appPath . 'event.php');
371
            }
372
373 1
            if (is_file($appPath . 'middleware.php')) {
374 1
                $this->app->middleware->import(include $appPath . 'middleware.php');
375
            }
376
377 1
            if (is_file($appPath . 'provider.php')) {
378 1
                $this->app->bind(include $appPath . 'provider.php');
379
            }
380
        }
381
382
        // 加载应用默认语言包
383 5
        $this->app->loadLangPack($this->app->lang->defaultLangSet());
384
385
        // 设置应用命名空间
386 5
        $this->app->setNamespace($this->app->config->get('app.app_namespace') ?: 'app\\' . $appName);
387 5
    }
388
389
    /**
390
     * HttpEnd
391
     * @param Response $response
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
392
     * @return void
393
     */
394 1
    public function end(Response $response): void
395
    {
396 1
        $this->app->event->trigger('HttpEnd', $response);
397
398
        // 写入日志
399 1
        $this->app->log->save();
400
        // 写入Session
401 1
        $this->app->session->save();
402 1
    }
403
404
    public function __debugInfo()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __debugInfo()
Loading history...
405
    {
406
        return [
407
            'path'       => $this->path,
408
            'multi'      => $this->multi,
409
            'bindDomain' => $this->bindDomain,
410
            'name'       => $this->name,
411
        ];
412
    }
413
}
414