Completed
Push — 6.0 ( 1e69d2...64aa8b )
by yun
02:11
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
169 33
        $this->config = array_merge($this->config, $this->app->config->get('route'));
170 33
    }
171
172 33
    protected function init()
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
     * 初始化默认域名
243
     * @access protected
244
     * @return void
245
     */
246 33
    protected function setDefaultDomain(): void
247
    {
248
        // 注册默认域名
249 33
        $domain = new Domain($this);
250
251 33
        $this->domains['-'] = $domain;
252
253
        // 默认分组
254 33
        $this->group = $domain;
255 33
    }
256
257
    /**
258
     * 设置当前分组
259
     * @access public
260
     * @param RuleGroup $group 域名
261
     * @return void
262
     */
263 33
    public function setGroup(RuleGroup $group): void
264
    {
265 33
        $this->group = $group;
266 33
    }
267
268
    /**
269
     * 获取指定标识的路由分组 不指定则获取当前分组
270
     * @access public
271
     * @param string $name 分组标识
272
     * @return RuleGroup
273
     */
274 33
    public function getGroup(string $name = null)
275
    {
276 33
        return $name ? $this->ruleName->getGroup($name) : $this->group;
277
    }
278
279
    /**
280
     * 注册变量规则
281
     * @access public
282
     * @param array $pattern 变量规则
283
     * @return $this
284
     */
285
    public function pattern(array $pattern)
286
    {
287
        $this->group->pattern($pattern);
288
289
        return $this;
290
    }
291
292
    /**
293
     * 注册路由参数
294
     * @access public
295
     * @param array $option 参数
296
     * @return $this
297
     */
298
    public function option(array $option)
299
    {
300
        $this->group->option($option);
301
302
        return $this;
303
    }
304
305
    /**
306
     * 注册域名路由
307
     * @access public
308
     * @param string|array $name 子域名
309
     * @param mixed        $rule 路由规则
310
     * @return Domain
311
     */
312 3
    public function domain($name, $rule = null): Domain
313
    {
314
        // 支持多个域名使用相同路由规则
315 3
        $domainName = is_array($name) ? array_shift($name) : $name;
316
317 3
        if (!isset($this->domains[$domainName])) {
318 3
            $domain = (new Domain($this, $domainName, $rule))
319 3
                ->lazy($this->lazy)
320 3
                ->removeSlash($this->removeSlash)
321 3
                ->mergeRuleRegex($this->mergeRuleRegex);
322
323 3
            $this->domains[$domainName] = $domain;
324
        } else {
325
            $domain = $this->domains[$domainName];
326
            $domain->parseGroupRule($rule);
327
        }
328
329 3
        if (is_array($name) && !empty($name)) {
330
            foreach ($name as $item) {
331
                $this->domains[$item] = $domainName;
332
            }
333
        }
334
335
        // 返回域名对象
336 3
        return $domain;
337
    }
338
339
    /**
340
     * 获取域名
341
     * @access public
342
     * @return array
343
     */
344
    public function getDomains(): array
345
    {
346
        return $this->domains;
347
    }
348
349
    /**
350
     * 获取RuleName对象
351
     * @access public
352
     * @return RuleName
353
     */
354 3
    public function getRuleName(): RuleName
355
    {
356 3
        return $this->ruleName;
357
    }
358
359
    /**
360
     * 设置路由绑定
361
     * @access public
362
     * @param string $bind   绑定信息
363
     * @param string $domain 域名
364
     * @return $this
365
     */
366
    public function bind(string $bind, string $domain = null)
367
    {
368
        $domain = is_null($domain) ? '-' : $domain;
369
370
        $this->bind[$domain] = $bind;
371
372
        return $this;
373
    }
374
375
    /**
376
     * 读取路由绑定信息
377
     * @access public
378
     * @return array
379
     */
380
    public function getBind(): array
381
    {
382
        return $this->bind;
383
    }
384
385
    /**
386
     * 读取路由绑定
387
     * @access public
388
     * @param string $domain 域名
389
     * @return string|null
390
     */
391 33
    public function getDomainBind(string $domain = null)
392
    {
393 33
        if (is_null($domain)) {
394 30
            $domain = $this->host;
395 3
        } elseif (false === strpos($domain, '.') && $this->request) {
396 3
            $domain .= '.' . $this->request->rootDomain();
397
        }
398
399 33
        if ($this->request) {
400 33
            $subDomain = $this->request->subDomain();
401
402 33
            if (strpos($subDomain, '.')) {
403
                $name = '*' . strstr($subDomain, '.');
404
            }
405
        }
406
407 33
        if (isset($this->bind[$domain])) {
408
            $result = $this->bind[$domain];
409 33
        } elseif (isset($name) && isset($this->bind[$name])) {
410
            $result = $this->bind[$name];
411 33
        } elseif (!empty($subDomain) && isset($this->bind['*'])) {
412
            $result = $this->bind['*'];
413
        } else {
414 33
            $result = null;
415
        }
416
417 33
        return $result;
418
    }
419
420
    /**
421
     * 读取路由标识
422
     * @access public
423
     * @param string $name   路由标识
424
     * @param string $domain 域名
425
     * @param string $method 请求类型
426
     * @return array
427
     */
428 3
    public function getName(string $name = null, string $domain = null, string $method = '*'): array
429
    {
430 3
        return $this->ruleName->getName($name, $domain, $method);
431
    }
432
433
    /**
434
     * 批量导入路由标识
435
     * @access public
436
     * @param array $name 路由标识
437
     * @return void
438
     */
439
    public function import(array $name): void
440
    {
441
        $this->ruleName->import($name);
442
    }
443
444
    /**
445
     * 注册路由标识
446
     * @access public
447
     * @param string   $name     路由标识
448
     * @param RuleItem $ruleItem 路由规则
449
     * @param bool     $first    是否优先
450
     * @return void
451
     */
452 12
    public function setName(string $name, RuleItem $ruleItem, bool $first = false): void
453
    {
454 12
        $this->ruleName->setName($name, $ruleItem, $first);
455 12
    }
456
457
    /**
458
     * 保存路由规则
459
     * @access public
460
     * @param string   $rule     路由规则
461
     * @param RuleItem $ruleItem RuleItem对象
462
     * @return void
463
     */
464 30
    public function setRule(string $rule, RuleItem $ruleItem = null): void
465
    {
466 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

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

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