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

Route::getDomainBind()   B

Complexity

Conditions 11
Paths 36

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 12.5763

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 17
c 1
b 0
f 0
nc 36
nop 1
dl 0
loc 27
ccs 13
cts 17
cp 0.7647
crap 12.5763
rs 7.3166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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