1
|
|
|
<?php |
2
|
|
|
// +---------------------------------------------------------------------- |
3
|
|
|
// | ThinkPHP [ WE CAN DO IT JUST THINK ] |
4
|
|
|
// +---------------------------------------------------------------------- |
5
|
|
|
// | Copyright (c) 2006~2021 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\event\AppInit; |
16
|
|
|
use think\helper\Str; |
17
|
|
|
use think\initializer\BootService; |
18
|
|
|
use think\initializer\Error; |
19
|
|
|
use think\initializer\RegisterService; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* App 基础类 |
23
|
|
|
* @property Route $route |
24
|
|
|
* @property Config $config |
25
|
|
|
* @property Cache $cache |
26
|
|
|
* @property Request $request |
27
|
|
|
* @property Http $http |
28
|
|
|
* @property Console $console |
29
|
|
|
* @property Env $env |
30
|
|
|
* @property Event $event |
31
|
|
|
* @property Middleware $middleware |
32
|
|
|
* @property Log $log |
33
|
|
|
* @property Lang $lang |
34
|
|
|
* @property Db $db |
35
|
|
|
* @property Cookie $cookie |
36
|
|
|
* @property Session $session |
37
|
|
|
* @property Validate $validate |
38
|
|
|
* @property Filesystem $filesystem |
39
|
|
|
*/ |
40
|
|
|
class App extends Container |
41
|
|
|
{ |
42
|
|
|
const VERSION = '6.0.15LTS'; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* 应用调试模式 |
46
|
|
|
* @var bool |
47
|
|
|
*/ |
48
|
|
|
protected $appDebug = false; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* 环境变量标识 |
52
|
|
|
* @var string |
53
|
|
|
*/ |
54
|
|
|
protected $envName = ''; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* 应用开始时间 |
58
|
|
|
* @var float |
59
|
|
|
*/ |
60
|
|
|
protected $beginTime; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* 应用内存初始占用 |
64
|
|
|
* @var integer |
65
|
|
|
*/ |
66
|
|
|
protected $beginMem; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* 当前应用类库命名空间 |
70
|
|
|
* @var string |
71
|
|
|
*/ |
72
|
|
|
protected $namespace = 'app'; |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* 应用根目录 |
76
|
|
|
* @var string |
77
|
|
|
*/ |
78
|
|
|
protected $rootPath = ''; |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* 框架目录 |
82
|
|
|
* @var string |
83
|
|
|
*/ |
84
|
|
|
protected $thinkPath = ''; |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* 应用目录 |
88
|
|
|
* @var string |
89
|
|
|
*/ |
90
|
|
|
protected $appPath = ''; |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Runtime目录 |
94
|
|
|
* @var string |
95
|
|
|
*/ |
96
|
|
|
protected $runtimePath = ''; |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* 路由定义目录 |
100
|
|
|
* @var string |
101
|
|
|
*/ |
102
|
|
|
protected $routePath = ''; |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* 配置后缀 |
106
|
|
|
* @var string |
107
|
|
|
*/ |
108
|
|
|
protected $configExt = '.php'; |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* 应用初始化器 |
112
|
|
|
* @var array |
113
|
|
|
*/ |
114
|
|
|
protected $initializers = [ |
115
|
|
|
Error::class, |
116
|
|
|
RegisterService::class, |
117
|
|
|
BootService::class, |
118
|
|
|
]; |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* 注册的系统服务 |
122
|
|
|
* @var array |
123
|
|
|
*/ |
124
|
|
|
protected $services = []; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* 初始化 |
128
|
|
|
* @var bool |
129
|
|
|
*/ |
130
|
|
|
protected $initialized = false; |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* 容器绑定标识 |
134
|
|
|
* @var array |
135
|
|
|
*/ |
136
|
|
|
protected $bind = [ |
137
|
|
|
'app' => App::class, |
138
|
|
|
'cache' => Cache::class, |
139
|
|
|
'config' => Config::class, |
140
|
|
|
'console' => Console::class, |
141
|
|
|
'cookie' => Cookie::class, |
142
|
|
|
'db' => Db::class, |
143
|
|
|
'env' => Env::class, |
144
|
|
|
'event' => Event::class, |
145
|
|
|
'http' => Http::class, |
146
|
|
|
'lang' => Lang::class, |
147
|
|
|
'log' => Log::class, |
148
|
|
|
'middleware' => Middleware::class, |
149
|
|
|
'request' => Request::class, |
150
|
|
|
'response' => Response::class, |
151
|
|
|
'route' => Route::class, |
152
|
|
|
'session' => Session::class, |
153
|
|
|
'validate' => Validate::class, |
154
|
|
|
'view' => View::class, |
155
|
|
|
'filesystem' => Filesystem::class, |
156
|
|
|
'think\DbManager' => Db::class, |
157
|
|
|
'think\LogManager' => Log::class, |
158
|
|
|
'think\CacheManager' => Cache::class, |
159
|
|
|
|
160
|
|
|
// 接口依赖注入 |
161
|
|
|
'Psr\Log\LoggerInterface' => Log::class, |
162
|
|
|
]; |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* 架构方法 |
166
|
|
|
* @access public |
167
|
|
|
* @param string $rootPath 应用根目录 |
168
|
|
|
*/ |
169
|
30 |
|
public function __construct(string $rootPath = '') |
170
|
|
|
{ |
171
|
30 |
|
$this->thinkPath = realpath(dirname(__DIR__)) . DIRECTORY_SEPARATOR; |
172
|
30 |
|
$this->rootPath = $rootPath ? rtrim($rootPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : $this->getDefaultRootPath(); |
173
|
30 |
|
$this->appPath = $this->rootPath . 'app' . DIRECTORY_SEPARATOR; |
174
|
30 |
|
$this->runtimePath = $this->rootPath . 'runtime' . DIRECTORY_SEPARATOR; |
175
|
|
|
|
176
|
30 |
|
if (is_file($this->appPath . 'provider.php')) { |
177
|
3 |
|
$this->bind(include $this->appPath . 'provider.php'); |
178
|
|
|
} |
179
|
|
|
|
180
|
30 |
|
static::setInstance($this); |
181
|
|
|
|
182
|
30 |
|
$this->instance('app', $this); |
183
|
30 |
|
$this->instance('think\Container', $this); |
184
|
30 |
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* 注册服务 |
188
|
|
|
* @access public |
189
|
|
|
* @param Service|string $service 服务 |
190
|
|
|
* @param bool $force 强制重新注册 |
191
|
|
|
* @return Service|null |
192
|
|
|
*/ |
193
|
3 |
|
public function register($service, bool $force = false) |
194
|
|
|
{ |
195
|
3 |
|
$registered = $this->getService($service); |
196
|
|
|
|
197
|
3 |
|
if ($registered && !$force) { |
198
|
3 |
|
return $registered; |
199
|
|
|
} |
200
|
|
|
|
201
|
3 |
|
if (is_string($service)) { |
202
|
3 |
|
$service = new $service($this); |
203
|
|
|
} |
204
|
|
|
|
205
|
3 |
|
if (method_exists($service, 'register')) { |
206
|
3 |
|
$service->register(); |
207
|
|
|
} |
208
|
|
|
|
209
|
3 |
|
if (property_exists($service, 'bind')) { |
210
|
3 |
|
$this->bind($service->bind); |
211
|
|
|
} |
212
|
|
|
|
213
|
3 |
|
$this->services[] = $service; |
214
|
3 |
|
} |
215
|
|
|
|
216
|
|
|
/** |
217
|
|
|
* 执行服务 |
218
|
|
|
* @access public |
219
|
|
|
* @param Service $service 服务 |
220
|
|
|
* @return mixed |
221
|
|
|
*/ |
222
|
3 |
|
public function bootService($service) |
223
|
|
|
{ |
224
|
3 |
|
if (method_exists($service, 'boot')) { |
225
|
3 |
|
return $this->invoke([$service, 'boot']); |
226
|
|
|
} |
227
|
3 |
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* 获取服务 |
231
|
|
|
* @param string|Service $service |
232
|
|
|
* @return Service|null |
233
|
|
|
*/ |
234
|
3 |
|
public function getService($service) |
235
|
|
|
{ |
236
|
3 |
|
$name = is_string($service) ? $service : get_class($service); |
237
|
|
|
return array_values(array_filter($this->services, function ($value) use ($name) { |
238
|
3 |
|
return $value instanceof $name; |
239
|
3 |
|
}, ARRAY_FILTER_USE_BOTH))[0] ?? null; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* 开启应用调试模式 |
244
|
|
|
* @access public |
245
|
|
|
* @param bool $debug 开启应用调试模式 |
246
|
|
|
* @return $this |
247
|
|
|
*/ |
248
|
6 |
|
public function debug(bool $debug = true) |
249
|
|
|
{ |
250
|
6 |
|
$this->appDebug = $debug; |
251
|
6 |
|
return $this; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* 是否为调试模式 |
256
|
|
|
* @access public |
257
|
|
|
* @return bool |
258
|
|
|
*/ |
259
|
3 |
|
public function isDebug(): bool |
260
|
|
|
{ |
261
|
3 |
|
return $this->appDebug; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* 设置应用命名空间 |
266
|
|
|
* @access public |
267
|
|
|
* @param string $namespace 应用命名空间 |
268
|
|
|
* @return $this |
269
|
|
|
*/ |
270
|
6 |
|
public function setNamespace(string $namespace) |
271
|
|
|
{ |
272
|
6 |
|
$this->namespace = $namespace; |
273
|
6 |
|
return $this; |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* 获取应用类库命名空间 |
278
|
|
|
* @access public |
279
|
|
|
* @return string |
280
|
|
|
*/ |
281
|
3 |
|
public function getNamespace(): string |
282
|
|
|
{ |
283
|
3 |
|
return $this->namespace; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* 设置环境变量标识 |
288
|
|
|
* @access public |
289
|
|
|
* @param string $name 环境标识 |
290
|
|
|
* @return $this |
291
|
|
|
*/ |
292
|
|
|
public function setEnvName(string $name) |
293
|
|
|
{ |
294
|
|
|
$this->envName = $name; |
295
|
|
|
return $this; |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* 获取框架版本 |
300
|
|
|
* @access public |
301
|
|
|
* @return string |
302
|
|
|
*/ |
303
|
3 |
|
public function version(): string |
304
|
|
|
{ |
305
|
3 |
|
return static::VERSION; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* 获取应用根目录 |
310
|
|
|
* @access public |
311
|
|
|
* @return string |
312
|
|
|
*/ |
313
|
12 |
|
public function getRootPath(): string |
314
|
|
|
{ |
315
|
12 |
|
return $this->rootPath; |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
/** |
319
|
|
|
* 获取应用基础目录 |
320
|
|
|
* @access public |
321
|
|
|
* @return string |
322
|
|
|
*/ |
323
|
3 |
|
public function getBasePath(): string |
324
|
|
|
{ |
325
|
3 |
|
return $this->rootPath . 'app' . DIRECTORY_SEPARATOR; |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
/** |
329
|
|
|
* 获取当前应用目录 |
330
|
|
|
* @access public |
331
|
|
|
* @return string |
332
|
|
|
*/ |
333
|
6 |
|
public function getAppPath(): string |
334
|
|
|
{ |
335
|
6 |
|
return $this->appPath; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* 设置应用目录 |
340
|
|
|
* @param string $path 应用目录 |
341
|
|
|
*/ |
342
|
3 |
|
public function setAppPath(string $path) |
343
|
|
|
{ |
344
|
3 |
|
$this->appPath = $path; |
345
|
3 |
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* 获取应用运行时目录 |
349
|
|
|
* @access public |
350
|
|
|
* @return string |
351
|
|
|
*/ |
352
|
42 |
|
public function getRuntimePath(): string |
353
|
|
|
{ |
354
|
42 |
|
return $this->runtimePath; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* 设置runtime目录 |
359
|
|
|
* @param string $path 定义目录 |
360
|
|
|
*/ |
361
|
3 |
|
public function setRuntimePath(string $path): void |
362
|
|
|
{ |
363
|
3 |
|
$this->runtimePath = $path; |
364
|
3 |
|
} |
365
|
|
|
|
366
|
|
|
/** |
367
|
|
|
* 获取核心框架目录 |
368
|
|
|
* @access public |
369
|
|
|
* @return string |
370
|
|
|
*/ |
371
|
3 |
|
public function getThinkPath(): string |
372
|
|
|
{ |
373
|
3 |
|
return $this->thinkPath; |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* 获取应用配置目录 |
378
|
|
|
* @access public |
379
|
|
|
* @return string |
380
|
|
|
*/ |
381
|
42 |
|
public function getConfigPath(): string |
382
|
|
|
{ |
383
|
42 |
|
return $this->rootPath . 'config' . DIRECTORY_SEPARATOR; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* 获取配置后缀 |
388
|
|
|
* @access public |
389
|
|
|
* @return string |
390
|
|
|
*/ |
391
|
39 |
|
public function getConfigExt(): string |
392
|
|
|
{ |
393
|
39 |
|
return $this->configExt; |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
/** |
397
|
|
|
* 获取应用开启时间 |
398
|
|
|
* @access public |
399
|
|
|
* @return float |
400
|
|
|
*/ |
401
|
3 |
|
public function getBeginTime(): float |
402
|
|
|
{ |
403
|
3 |
|
return $this->beginTime; |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
/** |
407
|
|
|
* 获取应用初始内存占用 |
408
|
|
|
* @access public |
409
|
|
|
* @return integer |
410
|
|
|
*/ |
411
|
3 |
|
public function getBeginMem(): int |
412
|
|
|
{ |
413
|
3 |
|
return $this->beginMem; |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
/** |
417
|
|
|
* 加载环境变量定义 |
418
|
|
|
* @access public |
419
|
|
|
* @param string $envName 环境标识 |
420
|
|
|
* @return void |
421
|
|
|
*/ |
422
|
3 |
|
public function loadEnv(string $envName = ''): void |
423
|
|
|
{ |
424
|
|
|
// 加载环境变量 |
425
|
3 |
|
$envFile = $envName ? $this->rootPath . '.env.' . $envName : $this->rootPath . '.env'; |
426
|
|
|
|
427
|
3 |
|
if (is_file($envFile)) { |
428
|
3 |
|
$this->env->load($envFile); |
429
|
|
|
} |
430
|
3 |
|
} |
431
|
|
|
|
432
|
|
|
/** |
433
|
|
|
* 初始化应用 |
434
|
|
|
* @access public |
435
|
|
|
* @return $this |
436
|
|
|
*/ |
437
|
3 |
|
public function initialize() |
438
|
|
|
{ |
439
|
3 |
|
$this->initialized = true; |
440
|
|
|
|
441
|
3 |
|
$this->beginTime = microtime(true); |
|
|
|
|
442
|
3 |
|
$this->beginMem = memory_get_usage(); |
443
|
|
|
|
444
|
3 |
|
$this->loadEnv($this->envName); |
445
|
|
|
|
446
|
3 |
|
$this->configExt = $this->env->get('config_ext', '.php'); |
|
|
|
|
447
|
|
|
|
448
|
3 |
|
$this->debugModeInit(); |
449
|
|
|
|
450
|
|
|
// 加载全局初始化文件 |
451
|
3 |
|
$this->load(); |
452
|
|
|
|
453
|
|
|
// 加载应用默认语言包 |
454
|
3 |
|
$this->loadLangPack(); |
455
|
|
|
|
456
|
3 |
|
// 监听AppInit |
457
|
|
|
$this->event->trigger(AppInit::class); |
458
|
|
|
|
459
|
3 |
|
date_default_timezone_set($this->config->get('app.default_timezone', 'Asia/Shanghai')); |
|
|
|
|
460
|
|
|
|
461
|
|
|
// 初始化 |
462
|
3 |
|
foreach ($this->initializers as $initializer) { |
463
|
|
|
$this->make($initializer)->init($this); |
464
|
3 |
|
} |
465
|
|
|
|
466
|
|
|
return $this; |
467
|
3 |
|
} |
468
|
3 |
|
|
469
|
|
|
/** |
470
|
|
|
* 是否初始化过 |
471
|
3 |
|
* @return bool |
472
|
|
|
*/ |
473
|
|
|
public function initialized() |
474
|
|
|
{ |
475
|
|
|
return $this->initialized; |
476
|
|
|
} |
477
|
|
|
|
478
|
6 |
|
/** |
479
|
|
|
* 加载语言包 |
480
|
6 |
|
* @return void |
481
|
|
|
*/ |
482
|
|
|
public function loadLangPack() |
483
|
|
|
{ |
484
|
|
|
// 加载默认语言包 |
485
|
|
|
$langSet = $this->lang->defaultLangSet(); |
486
|
|
|
$this->lang->switchLangSet($langSet); |
487
|
|
|
} |
488
|
3 |
|
|
489
|
|
|
/** |
490
|
3 |
|
* 引导应用 |
491
|
|
|
* @access public |
492
|
|
|
* @return void |
493
|
|
|
*/ |
494
|
|
|
public function boot(): void |
495
|
3 |
|
{ |
496
|
3 |
|
array_walk($this->services, function ($service) { |
497
|
|
|
$this->bootService($service); |
498
|
|
|
}); |
499
|
3 |
|
} |
500
|
|
|
|
501
|
3 |
|
/** |
502
|
|
|
* 加载应用文件和配置 |
503
|
|
|
* @access protected |
504
|
3 |
|
* @return void |
505
|
|
|
*/ |
506
|
|
|
protected function load(): void |
507
|
|
|
{ |
508
|
|
|
$appPath = $this->getAppPath(); |
509
|
|
|
|
510
|
|
|
if (is_file($appPath . 'common.php')) { |
511
|
3 |
|
include_once $appPath . 'common.php'; |
512
|
|
|
} |
513
|
|
|
|
514
|
3 |
|
include_once $this->thinkPath . 'helper.php'; |
515
|
3 |
|
|
516
|
3 |
|
$configPath = $this->getConfigPath(); |
517
|
|
|
|
518
|
|
|
$files = []; |
519
|
|
|
|
520
|
|
|
if (is_dir($configPath)) { |
521
|
|
|
$files = glob($configPath . '*' . $this->configExt); |
522
|
|
|
} |
523
|
3 |
|
|
524
|
|
|
foreach ($files as $file) { |
525
|
3 |
|
$this->config->load($file, pathinfo($file, PATHINFO_FILENAME)); |
|
|
|
|
526
|
|
|
} |
527
|
3 |
|
|
528
|
3 |
|
if (is_file($appPath . 'event.php')) { |
529
|
|
|
$this->loadEvent(include $appPath . 'event.php'); |
530
|
|
|
} |
531
|
3 |
|
|
532
|
|
|
if (is_file($appPath . 'service.php')) { |
533
|
3 |
|
$services = include $appPath . 'service.php'; |
534
|
|
|
foreach ($services as $service) { |
535
|
3 |
|
$this->register($service); |
536
|
|
|
} |
537
|
3 |
|
} |
538
|
3 |
|
} |
539
|
|
|
|
540
|
|
|
/** |
541
|
3 |
|
* 调试模式设置 |
542
|
|
|
* @access protected |
543
|
|
|
* @return void |
544
|
|
|
*/ |
545
|
3 |
|
protected function debugModeInit(): void |
546
|
3 |
|
{ |
547
|
|
|
// 应用调试模式 |
548
|
|
|
if (!$this->appDebug) { |
549
|
3 |
|
$this->appDebug = $this->env->get('app_debug') ? true : false; |
550
|
|
|
ini_set('display_errors', 'Off'); |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
if (!$this->runningInConsole()) { |
554
|
|
|
//重新申请一块比较大的buffer |
555
|
3 |
|
if (ob_get_level() > 0) { |
556
|
|
|
$output = ob_get_clean(); |
557
|
|
|
} |
558
|
|
|
ob_start(); |
559
|
|
|
if (!empty($output)) { |
560
|
|
|
echo $output; |
561
|
|
|
} |
562
|
3 |
|
} |
563
|
|
|
} |
564
|
|
|
|
565
|
3 |
|
/** |
566
|
3 |
|
* 注册应用事件 |
567
|
3 |
|
* @access protected |
568
|
|
|
* @param array $event 事件数据 |
569
|
|
|
* @return void |
570
|
3 |
|
*/ |
571
|
|
|
public function loadEvent(array $event): void |
572
|
|
|
{ |
573
|
|
|
if (isset($event['bind'])) { |
574
|
|
|
$this->event->bind($event['bind']); |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
if (isset($event['listen'])) { |
578
|
|
|
$this->event->listenEvents($event['listen']); |
579
|
|
|
} |
580
|
3 |
|
|
581
|
|
|
if (isset($event['subscribe'])) { |
582
|
|
|
$this->event->subscribe($event['subscribe']); |
583
|
|
|
} |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
/** |
587
|
|
|
* 解析应用类的类名 |
588
|
3 |
|
* @access public |
589
|
|
|
* @param string $layer 层名 controller model ... |
590
|
3 |
|
* @param string $name 类名 |
591
|
3 |
|
* @return string |
592
|
|
|
*/ |
593
|
|
|
public function parseClass(string $layer, string $name): string |
594
|
3 |
|
{ |
595
|
3 |
|
$name = str_replace(['/', '.'], '\\', $name); |
596
|
|
|
$array = explode('\\', $name); |
597
|
|
|
$class = Str::studly(array_pop($array)); |
598
|
3 |
|
$path = $array ? implode('\\', $array) . '\\' : ''; |
599
|
3 |
|
|
600
|
|
|
return $this->namespace . '\\' . $layer . '\\' . $path . $class; |
601
|
3 |
|
} |
602
|
|
|
|
603
|
|
|
/** |
604
|
|
|
* 是否运行在命令行下 |
605
|
|
|
* @return bool |
606
|
|
|
*/ |
607
|
|
|
public function runningInConsole(): bool |
608
|
|
|
{ |
609
|
|
|
return php_sapi_name() === 'cli' || php_sapi_name() === 'phpdbg'; |
610
|
6 |
|
} |
611
|
|
|
|
612
|
6 |
|
/** |
613
|
6 |
|
* 获取应用根目录 |
614
|
6 |
|
* @access protected |
615
|
6 |
|
* @return string |
616
|
|
|
*/ |
617
|
6 |
|
protected function getDefaultRootPath(): string |
618
|
|
|
{ |
619
|
|
|
return dirname($this->thinkPath, 4) . DIRECTORY_SEPARATOR; |
620
|
|
|
} |
621
|
|
|
|
622
|
|
|
} |
623
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.