Passed
Pull Request — 6.0 (#2291)
by
unknown
02:15
created

Route::setRule()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
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\RouteNotFoundException;
17
use think\route\Dispatch;
18
use think\route\dispatch\Callback;
19
use think\route\dispatch\Url as UrlDispatch;
20
use think\route\Domain;
21
use think\route\Resource;
22
use think\route\Rule;
23
use think\route\RuleGroup;
24
use think\route\RuleItem;
25
use think\route\RuleName;
26
use think\route\Url as UrlBuild;
27
28
/**
29
 * 路由管理类
30
 * @package think
31
 */
32
class Route
33
{
34
    /**
35
     * REST定义
36
     * @var array
37
     */
38
    protected $rest = [
39
        'index'  => ['get', '', 'index'],
40
        'create' => ['get', '/create', 'create'],
41
        'edit'   => ['get', '/<id>/edit', 'edit'],
42
        'read'   => ['get', '/<id>', 'read'],
43
        'save'   => ['post', '', 'save'],
44
        'update' => ['put', '/<id>', 'update'],
45
        'delete' => ['delete', '/<id>', 'delete'],
46
    ];
47
48
    /**
49
     * 配置参数
50
     * @var array
51
     */
52
    protected $config = [
53
        // pathinfo分隔符
54
        'pathinfo_depr'         => '/',
55
        // 是否开启路由延迟解析
56
        'url_lazy_route'        => false,
57
        // 是否强制使用路由
58
        'url_route_must'        => false,
59
        // 合并路由规则
60
        'route_rule_merge'      => false,
61
        // 路由是否完全匹配
62
        'route_complete_match'  => false,
63
        // 去除斜杠
64
        'remove_slash'          => false,
65
        // 使用注解路由
66
        'route_annotation'      => false,
67
        // 默认的路由变量规则
68
        'default_route_pattern' => '[\w\.]+',
69
        // URL伪静态后缀
70
        'url_html_suffix'       => 'html',
71
        // 访问控制器层名称
72
        'controller_layer'      => 'controller',
73
        // 空控制器名
74
        'empty_controller'      => 'Error',
75
        // 是否使用控制器后缀
76
        'controller_suffix'     => false,
77
        // 默认控制器名
78
        'default_controller'    => 'Index',
79
        // 默认操作名
80
        'default_action'        => 'index',
81
        // 操作方法后缀
82
        'action_suffix'         => '',
83
        // 非路由变量是否使用普通参数方式(用于URL生成)
84
        'url_common_param'      => true,
85
    ];
86
87
    /**
88
     * 当前应用
89
     * @var App
90
     */
91
    protected $app;
92
93
    /**
94
     * 请求对象
95
     * @var Request
96
     */
97
    protected $request;
98
99
    /**
100
     * @var RuleName
101
     */
102
    protected $ruleName;
103
104
    /**
105
     * 当前HOST
106
     * @var string
107
     */
108
    protected $host;
109
110
    /**
111
     * 当前分组对象
112
     * @var RuleGroup
113
     */
114
    protected $group;
115
116
    /**
117
     * 路由绑定
118
     * @var array
119
     */
120
    protected $bind = [];
121
122
    /**
123
     * 域名对象
124
     * @var Domain[]
125
     */
126
    protected $domains = [];
127
128
    /**
129
     * 跨域路由规则
130
     * @var RuleGroup
131
     */
132
    protected $cross;
133
134
    /**
135
     * 路由是否延迟解析
136
     * @var bool
137
     */
138
    protected $lazy = false;
139
140
    /**
141
     * 路由是否测试模式
142
     * @var bool
143
     */
144
    protected $isTest = false;
145
146
    /**
147
     * (分组)路由规则是否合并解析
148
     * @var bool
149
     */
150
    protected $mergeRuleRegex = false;
151
152
    /**
153
     * 是否去除URL最后的斜线
154
     * @var bool
155
     */
156
    protected $removeSlash = false;
157
158 33
    public function __construct(App $app)
159
    {
160 33
        $this->app      = $app;
161 33
        $this->ruleName = new RuleName();
162 33
        $this->setDefaultDomain();
163
164 33
        if (is_file($this->app->getRuntimePath() . 'route.php')) {
165
            // 读取路由映射文件
166
            $this->import(include $this->app->getRuntimePath() . 'route.php');
167
        }
168 33
    }
169
170 33
    protected function init()
171
    {
172 33
        $this->config = array_merge($this->config, $this->app->config->get('route'));
173
174 33
        if (!empty($this->config['middleware'])) {
175
            $this->app->middleware->import($this->config['middleware'], 'route');
176
        }
177
178 33
        $this->lazy($this->config['url_lazy_route']);
179 33
        $this->mergeRuleRegex = $this->config['route_rule_merge'];
180 33
        $this->removeSlash    = $this->config['remove_slash'];
181
182 33
        $this->group->removeSlash($this->removeSlash);
183 33
    }
184
185 33
    public function config(string $name = null)
186
    {
187 33
        if (is_null($name)) {
188
            return $this->config;
189
        }
190
191 33
        return $this->config[$name] ?? null;
192
    }
193
194
    /**
195
     * 设置路由域名及分组(包括资源路由)是否延迟解析
196
     * @access public
197
     * @param bool $lazy 路由是否延迟解析
198
     * @return $this
199
     */
200 33
    public function lazy(bool $lazy = true)
201
    {
202 33
        $this->lazy = $lazy;
203 33
        return $this;
204
    }
205
206
    /**
207
     * 设置路由为测试模式
208
     * @access public
209
     * @param bool $test 路由是否测试模式
210
     * @return void
211
     */
212
    public function setTestMode(bool $test): void
213
    {
214
        $this->isTest = $test;
215
    }
216
217
    /**
218
     * 检查路由是否为测试模式
219
     * @access public
220
     * @return bool
221
     */
222 6
    public function isTest(): bool
223
    {
224 6
        return $this->isTest;
225
    }
226
227
    /**
228
     * 设置路由域名及分组(包括资源路由)是否合并解析
229
     * @access public
230
     * @param bool $merge 路由是否合并解析
231
     * @return $this
232
     */
233
    public function mergeRuleRegex(bool $merge = true)
234
    {
235
        $this->mergeRuleRegex = $merge;
236
        $this->group->mergeRuleRegex($merge);
237
238
        return $this;
239
    }
240
    
241
     /**
242
     * 设置request属性
243
     * @param Request $request
244
     * @return $this
245
     */
246
    public function setRequest(Request $request)
247
    {
248
        $this->request = $request;
249
        return $this;
250
    }
251
252
    /**
253
     * 初始化默认域名
254
     * @access protected
255
     * @return void
256
     */
257 33
    protected function setDefaultDomain(): void
258
    {
259
        // 注册默认域名
260 33
        $domain = new Domain($this);
261
262 33
        $this->domains['-'] = $domain;
263
264
        // 默认分组
265 33
        $this->group = $domain;
266 33
    }
267
268
    /**
269
     * 设置当前分组
270
     * @access public
271
     * @param RuleGroup $group 域名
272
     * @return void
273
     */
274 33
    public function setGroup(RuleGroup $group): void
275
    {
276 33
        $this->group = $group;
277 33
    }
278
279
    /**
280
     * 获取指定标识的路由分组 不指定则获取当前分组
281
     * @access public
282
     * @param string $name 分组标识
283
     * @return RuleGroup
284
     */
285 33
    public function getGroup(string $name = null)
286
    {
287 33
        return $name ? $this->ruleName->getGroup($name) : $this->group;
288
    }
289
290
    /**
291
     * 注册变量规则
292
     * @access public
293
     * @param array $pattern 变量规则
294
     * @return $this
295
     */
296
    public function pattern(array $pattern)
297
    {
298
        $this->group->pattern($pattern);
299
300
        return $this;
301
    }
302
303
    /**
304
     * 注册路由参数
305
     * @access public
306
     * @param array $option 参数
307
     * @return $this
308
     */
309
    public function option(array $option)
310
    {
311
        $this->group->option($option);
312
313
        return $this;
314
    }
315
316
    /**
317
     * 注册域名路由
318
     * @access public
319
     * @param string|array $name 子域名
320
     * @param mixed        $rule 路由规则
321
     * @return Domain
322
     */
323 3
    public function domain($name, $rule = null): Domain
324
    {
325
        // 支持多个域名使用相同路由规则
326 3
        $domainName = is_array($name) ? array_shift($name) : $name;
327
328 3
        if (!isset($this->domains[$domainName])) {
329 3
            $domain = (new Domain($this, $domainName, $rule))
330 3
                ->lazy($this->lazy)
331 3
                ->removeSlash($this->removeSlash)
332 3
                ->mergeRuleRegex($this->mergeRuleRegex);
333
334 3
            $this->domains[$domainName] = $domain;
335
        } else {
336
            $domain = $this->domains[$domainName];
337
            $domain->parseGroupRule($rule);
338
        }
339
340 3
        if (is_array($name) && !empty($name)) {
341
            foreach ($name as $item) {
342
                $this->domains[$item] = $domainName;
343
            }
344
        }
345
346
        // 返回域名对象
347 3
        return $domain;
348
    }
349
350
    /**
351
     * 获取域名
352
     * @access public
353
     * @return array
354
     */
355
    public function getDomains(): array
356
    {
357
        return $this->domains;
358
    }
359
360
    /**
361
     * 获取RuleName对象
362
     * @access public
363
     * @return RuleName
364
     */
365 3
    public function getRuleName(): RuleName
366
    {
367 3
        return $this->ruleName;
368
    }
369
370
    /**
371
     * 设置路由绑定
372
     * @access public
373
     * @param string $bind   绑定信息
374
     * @param string $domain 域名
375
     * @return $this
376
     */
377
    public function bind(string $bind, string $domain = null)
378
    {
379
        $domain = is_null($domain) ? '-' : $domain;
380
381
        $this->bind[$domain] = $bind;
382
383
        return $this;
384
    }
385
386
    /**
387
     * 读取路由绑定信息
388
     * @access public
389
     * @return array
390
     */
391
    public function getBind(): array
392
    {
393
        return $this->bind;
394
    }
395
396
    /**
397
     * 读取路由绑定
398
     * @access public
399
     * @param string $domain 域名
400
     * @return string|null
401
     */
402 33
    public function getDomainBind(string $domain = null)
403
    {
404 33
        if (is_null($domain)) {
405 30
            $domain = $this->host;
406 3
        } elseif (false === strpos($domain, '.') && $this->request) {
407 3
            $domain .= '.' . $this->request->rootDomain();
408
        }
409
410 33
        if ($this->request) {
411 33
            $subDomain = $this->request->subDomain();
412
413 33
            if (strpos($subDomain, '.')) {
414
                $name = '*' . strstr($subDomain, '.');
415
            }
416
        }
417
418 33
        if (isset($this->bind[$domain])) {
419
            $result = $this->bind[$domain];
420 33
        } elseif (isset($name) && isset($this->bind[$name])) {
421
            $result = $this->bind[$name];
422 33
        } elseif (!empty($subDomain) && isset($this->bind['*'])) {
423
            $result = $this->bind['*'];
424
        } else {
425 33
            $result = null;
426
        }
427
428 33
        return $result;
429
    }
430
431
    /**
432
     * 读取路由标识
433
     * @access public
434
     * @param string $name   路由标识
435
     * @param string $domain 域名
436
     * @param string $method 请求类型
437
     * @return RuleItem[]
438
     */
439 3
    public function getName(string $name = null, string $domain = null, string $method = '*'): array
440
    {
441 3
        return $this->ruleName->getName($name, $domain, $method);
442
    }
443
444
    /**
445
     * 批量导入路由标识
446
     * @access public
447
     * @param array $name 路由标识
448
     * @return void
449
     */
450
    public function import(array $name): void
451
    {
452
        $this->ruleName->import($name);
453
    }
454
455
    /**
456
     * 注册路由标识
457
     * @access public
458
     * @param string   $name     路由标识
459
     * @param RuleItem $ruleItem 路由规则
460
     * @param bool     $first    是否优先
461
     * @return void
462
     */
463 12
    public function setName(string $name, RuleItem $ruleItem, bool $first = false): void
464
    {
465 12
        $this->ruleName->setName($name, $ruleItem, $first);
466 12
    }
467
468
    /**
469
     * 保存路由规则
470
     * @access public
471
     * @param string   $rule     路由规则
472
     * @param RuleItem $ruleItem RuleItem对象
473
     * @return void
474
     */
475 30
    public function setRule(string $rule, RuleItem $ruleItem = null): void
476
    {
477 30
        $this->ruleName->setRule($rule, $ruleItem);
0 ignored issues
show
Bug introduced by
It seems like $ruleItem can also be of type null; however, parameter $ruleItem of think\route\RuleName::setRule() does only seem to accept think\route\RuleItem, 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

477
        $this->ruleName->setRule($rule, /** @scrutinizer ignore-type */ $ruleItem);
Loading history...
478 30
    }
479
480
    /**
481
     * 读取路由
482
     * @access public
483
     * @param string $rule 路由规则
484
     * @return RuleItem[]
485
     */
486 3
    public function getRule(string $rule): array
487
    {
488 3
        return $this->ruleName->getRule($rule);
489
    }
490
491
    /**
492
     * 读取路由列表
493
     * @access public
494
     * @return array
495
     */
496
    public function getRuleList(): array
497
    {
498
        return $this->ruleName->getRuleList();
499
    }
500
501
    /**
502
     * 清空路由规则
503
     * @access public
504
     * @return void
505
     */
506
    public function clear(): void
507
    {
508
        $this->ruleName->clear();
509
510
        if ($this->group) {
511
            $this->group->clear();
512
        }
513
    }
514
515
    /**
516
     * 注册路由规则
517
     * @access public
518
     * @param string $rule   路由规则
519
     * @param mixed  $route  路由地址
520
     * @param string $method 请求类型
521
     * @return RuleItem
522
     */
523 30
    public function rule(string $rule, $route = null, string $method = '*'): RuleItem
524
    {
525 30
        if ($route instanceof Response) {
526
            // 兼容之前的路由到响应对象,感觉不需要,使用场景很少,闭包就能实现
527
            $route = function () use ($route) {
528 3
                return $route;
529 3
            };
530
        }
531 30
        return $this->group->addRule($rule, $route, $method);
532
    }
533
534
    /**
535
     * 设置跨域有效路由规则
536
     * @access public
537
     * @param Rule   $rule   路由规则
538
     * @param string $method 请求类型
539
     * @return $this
540
     */
541
    public function setCrossDomainRule(Rule $rule, string $method = '*')
542
    {
543
        if (!isset($this->cross)) {
544
            $this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex);
545
        }
546
547
        $this->cross->addRuleItem($rule, $method);
548
549
        return $this;
550
    }
551
552
    /**
553
     * 注册路由分组
554
     * @access public
555
     * @param string|\Closure $name  分组名称或者参数
556
     * @param mixed           $route 分组路由
557
     * @return RuleGroup
558
     */
559 6
    public function group($name, $route = null): RuleGroup
560
    {
561 6
        if ($name instanceof Closure) {
562 6
            $route = $name;
563 6
            $name  = '';
564
        }
565
566 6
        return (new RuleGroup($this, $this->group, $name, $route))
567 6
            ->lazy($this->lazy)
568 6
            ->removeSlash($this->removeSlash)
569 6
            ->mergeRuleRegex($this->mergeRuleRegex);
570
    }
571
572
    /**
573
     * 注册路由
574
     * @access public
575
     * @param string $rule  路由规则
576
     * @param mixed  $route 路由地址
577
     * @return RuleItem
578
     */
579
    public function any(string $rule, $route): RuleItem
580
    {
581
        return $this->rule($rule, $route, '*');
582
    }
583
584
    /**
585
     * 注册GET路由
586
     * @access public
587
     * @param string $rule  路由规则
588
     * @param mixed  $route 路由地址
589
     * @return RuleItem
590
     */
591 24
    public function get(string $rule, $route): RuleItem
592
    {
593 24
        return $this->rule($rule, $route, 'GET');
594
    }
595
596
    /**
597
     * 注册POST路由
598
     * @access public
599
     * @param string $rule  路由规则
600
     * @param mixed  $route 路由地址
601
     * @return RuleItem
602
     */
603 6
    public function post(string $rule, $route): RuleItem
604
    {
605 6
        return $this->rule($rule, $route, 'POST');
606
    }
607
608
    /**
609
     * 注册PUT路由
610
     * @access public
611
     * @param string $rule  路由规则
612
     * @param mixed  $route 路由地址
613
     * @return RuleItem
614
     */
615 6
    public function put(string $rule, $route): RuleItem
616
    {
617 6
        return $this->rule($rule, $route, 'PUT');
618
    }
619
620
    /**
621
     * 注册DELETE路由
622
     * @access public
623
     * @param string $rule  路由规则
624
     * @param mixed  $route 路由地址
625
     * @return RuleItem
626
     */
627
    public function delete(string $rule, $route): RuleItem
628
    {
629
        return $this->rule($rule, $route, 'DELETE');
630
    }
631
632
    /**
633
     * 注册PATCH路由
634
     * @access public
635
     * @param string $rule  路由规则
636
     * @param mixed  $route 路由地址
637
     * @return RuleItem
638
     */
639
    public function patch(string $rule, $route): RuleItem
640
    {
641
        return $this->rule($rule, $route, 'PATCH');
642
    }
643
644
    /**
645
     * 注册OPTIONS路由
646
     * @access public
647
     * @param string $rule  路由规则
648
     * @param mixed  $route 路由地址
649
     * @return RuleItem
650
     */
651
    public function options(string $rule, $route): RuleItem
652
    {
653
        return $this->rule($rule, $route, 'OPTIONS');
654
    }
655
656
    /**
657
     * 注册资源路由
658
     * @access public
659
     * @param string $rule  路由规则
660
     * @param string $route 路由地址
661
     * @return Resource
662
     */
663 3
    public function resource(string $rule, string $route): Resource
664
    {
665 3
        return (new Resource($this, $this->group, $rule, $route, $this->rest))
666 3
            ->lazy($this->lazy);
667
    }
668
669
    /**
670
     * 注册视图路由
671
     * @access public
672
     * @param string $rule     路由规则
673
     * @param string $template 路由模板地址
674
     * @param array  $vars     模板变量
675
     * @return RuleItem
676
     */
677 3
    public function view(string $rule, string $template = '', array $vars = []): RuleItem
678
    {
679
        return $this->rule($rule, function () use ($vars, $template) {
680 3
            return Response::create($template, 'view')->assign($vars);
0 ignored issues
show
Bug introduced by
The method assign() does not exist on think\Response. It seems like you code against a sub-type of think\Response such as think\response\View. ( Ignorable by Annotation )

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

680
            return Response::create($template, 'view')->/** @scrutinizer ignore-call */ assign($vars);
Loading history...
681 3
        }, 'GET');
682
    }
683
684
    /**
685
     * 注册重定向路由
686
     * @access public
687
     * @param string $rule   路由规则
688
     * @param string $route  路由地址
689
     * @param int    $status 状态码
690
     * @return RuleItem
691
     */
692 3
    public function redirect(string $rule, string $route = '', int $status = 301): RuleItem
693
    {
694
        return $this->rule($rule, function () use ($status, $route) {
695 3
            return Response::create($route, 'redirect')->code($status);
696 3
        }, '*');
697
    }
698
699
    /**
700
     * rest方法定义和修改
701
     * @access public
702
     * @param string|array $name     方法名称
703
     * @param array|bool   $resource 资源
704
     * @return $this
705
     */
706
    public function rest($name, $resource = [])
707
    {
708
        if (is_array($name)) {
709
            $this->rest = $resource ? $name : array_merge($this->rest, $name);
710
        } else {
711
            $this->rest[$name] = $resource;
712
        }
713
714
        return $this;
715
    }
716
717
    /**
718
     * 获取rest方法定义的参数
719
     * @access public
720
     * @param string $name 方法名称
721
     * @return array|null
722
     */
723
    public function getRest(string $name = null)
724
    {
725
        if (is_null($name)) {
726
            return $this->rest;
727
        }
728
729
        return $this->rest[$name] ?? null;
730
    }
731
732
    /**
733
     * 注册未匹配路由规则后的处理
734
     * @access public
735
     * @param string|Closure $route  路由地址
736
     * @param string         $method 请求类型
737
     * @return RuleItem
738
     */
739
    public function miss($route, string $method = '*'): RuleItem
740
    {
741
        return $this->group->miss($route, $method);
742
    }
743
744
    /**
745
     * 路由调度
746
     * @param Request $request
747
     * @param Closure|bool $withRoute
748
     * @return Response
749
     */
750 33
    public function dispatch(Request $request, $withRoute = true)
751
    {
752 33
        $this->request = $request;
753 33
        $this->host    = $this->request->host(true);
754 33
        $this->init();
755
756 33
        if ($withRoute) {
757
            //加载路由
758 33
            if ($withRoute instanceof Closure) {
759
                $withRoute();
760
            }
761 33
            $dispatch = $this->check();
762
        } else {
763
            $dispatch = $this->url($this->path());
764
        }
765
766 33
        $dispatch->init($this->app);
767
768 33
        return $this->app->middleware->pipeline('route')
769 33
            ->send($request)
770
            ->then(function () use ($dispatch) {
771 33
                return $dispatch->run();
772 33
            });
773
    }
774
775
    /**
776
     * 检测URL路由
777
     * @access public
778
     * @return Dispatch|false
779
     * @throws RouteNotFoundException
780
     */
781 33
    public function check()
782
    {
783
        // 自动检测域名路由
784 33
        $url = str_replace($this->config['pathinfo_depr'], '|', $this->path());
785
786 33
        $completeMatch = $this->config['route_complete_match'];
787
788 33
        $result = $this->checkDomain()->check($this->request, $url, $completeMatch);
789
790 33
        if (false === $result && !empty($this->cross)) {
791
            // 检测跨域路由
792
            $result = $this->cross->check($this->request, $url, $completeMatch);
793
        }
794
795 33
        if (false !== $result) {
796 30
            return $result;
797 9
        } elseif ($this->config['url_route_must']) {
798
            throw new RouteNotFoundException();
799
        }
800
801 9
        return $this->url($url);
802
    }
803
804
    /**
805
     * 获取当前请求URL的pathinfo信息(不含URL后缀)
806
     * @access protected
807
     * @return string
808
     */
809 33
    protected function path(): string
810
    {
811 33
        $suffix   = $this->config['url_html_suffix'];
812 33
        $pathinfo = $this->request->pathinfo();
813
814 33
        if (false === $suffix) {
815
            // 禁止伪静态访问
816
            $path = $pathinfo;
817 33
        } elseif ($suffix) {
818
            // 去除正常的URL后缀
819 33
            $path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
820
        } else {
821
            // 允许任何后缀访问
822
            $path = preg_replace('/\.' . $this->request->ext() . '$/i', '', $pathinfo);
823
        }
824
825 33
        return $path;
826
    }
827
828
    /**
829
     * 默认URL解析
830
     * @access public
831
     * @param string $url URL地址
832
     * @return Dispatch
833
     */
834 9
    public function url(string $url): Dispatch
835
    {
836 9
        if ($this->request->method() == 'OPTIONS') {
837
            // 自动响应options请求
838
            return new Callback($this->request, $this->group, function () {
839 6
                return Response::create('', 'html', 204)->header(['Allow' => 'GET, POST, PUT, DELETE']);
840 6
            });
841
        }
842
843 3
        return new UrlDispatch($this->request, $this->group, $url);
844
    }
845
846
    /**
847
     * 检测域名的路由规则
848
     * @access protected
849
     * @return Domain
850
     */
851 33
    protected function checkDomain(): Domain
852
    {
853 33
        $item = false;
854
855 33
        if (count($this->domains) > 1) {
856
            // 获取当前子域名
857 3
            $subDomain = $this->request->subDomain();
858
859 3
            $domain  = $subDomain ? explode('.', $subDomain) : [];
860 3
            $domain2 = $domain ? array_pop($domain) : '';
861
862 3
            if ($domain) {
863
                // 存在三级域名
864
                $domain3 = array_pop($domain);
865
            }
866
867 3
            if (isset($this->domains[$this->host])) {
868
                // 子域名配置
869
                $item = $this->domains[$this->host];
870 3
            } elseif (isset($this->domains[$subDomain])) {
871 3
                $item = $this->domains[$subDomain];
872
            } elseif (isset($this->domains['*.' . $domain2]) && !empty($domain3)) {
873
                // 泛三级域名
874
                $item      = $this->domains['*.' . $domain2];
875
                $panDomain = $domain3;
876
            } elseif (isset($this->domains['*']) && !empty($domain2)) {
877
                // 泛二级域名
878
                if ('www' != $domain2) {
879
                    $item      = $this->domains['*'];
880
                    $panDomain = $domain2;
881
                }
882
            }
883
884 3
            if (isset($panDomain)) {
885
                // 保存当前泛域名
886
                $this->request->setPanDomain($panDomain);
887
            }
888
        }
889
890 33
        if (false === $item) {
891
            // 检测全局域名规则
892 30
            $item = $this->domains['-'];
893
        }
894
895 33
        if (is_string($item)) {
896
            $item = $this->domains[$item];
897
        }
898
899 33
        return $item;
900
    }
901
902
    /**
903
     * URL生成 支持路由反射
904
     * @access public
905
     * @param string $url  路由地址
906
     * @param array  $vars 参数 ['a'=>'val1', 'b'=>'val2']
907
     * @return UrlBuild
908
     */
909
    public function buildUrl(string $url = '', array $vars = []): UrlBuild
910
    {
911
        return $this->app->make(UrlBuild::class, [$this, $this->app, $url, $vars], true);
912
    }
913
914
    /**
915
     * 设置全局的路由分组参数
916
     * @access public
917
     * @param string $method 方法名
918
     * @param array  $args   调用参数
919
     * @return RuleGroup
920
     */
921
    public function __call($method, $args)
922
    {
923
        return call_user_func_array([$this->group, $method], $args);
924
    }
925
}
926