Passed
Push — 8.0 ( f31d17...521226 )
by liu
02:19
created

Route::mergeRuleRegex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2023 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\Domain;
19
use think\route\Resource;
20
use think\route\ResourceRegister;
21
use think\route\Rule;
22
use think\route\RuleGroup;
23
use think\route\RuleItem;
24
use think\route\RuleName;
25
use think\route\Url as UrlBuild;
26
27
/**
28
 * 路由管理类
29
 * @package think
30
 */
31
class Route
32
{
33
    /**
34
     * REST定义
35
     * @var array
36
     */
37
    protected $rest = [
38
        'index'  => ['get', '', 'index'],
39
        'create' => ['get', '/create', 'create'],
40
        'edit'   => ['get', '/<id>/edit', 'edit'],
41
        'read'   => ['get', '/<id>', 'read'],
42
        'save'   => ['post', '', 'save'],
43
        'update' => ['put', '/<id>', 'update'],
44
        'delete' => ['delete', '/<id>', 'delete'],
45
    ];
46
47
    /**
48
     * 配置参数
49
     * @var array
50
     */
51
    protected $config = [
52
        // pathinfo分隔符
53
        'pathinfo_depr'         => '/',
54
        // 是否开启路由延迟解析
55
        'url_lazy_route'        => false,
56
        // 是否强制使用路由
57
        'url_route_must'        => false,
58
        // 是否区分大小写
59
        'url_case_sensitive'    => false,
60
        // 合并路由规则
61
        'route_rule_merge'      => false,
62
        // 路由是否完全匹配
63
        'route_complete_match'  => false,
64
        // 去除斜杠
65
        'remove_slash'          => false,
66
        // 使用注解路由
67
        'route_annotation'      => false,
68
        // 默认的路由变量规则
69
        'default_route_pattern' => '[\w\.]+',
70
        // URL伪静态后缀
71
        'url_html_suffix'       => 'html',
72
        // 访问控制器层名称
73
        'controller_layer'      => 'controller',
74
        // 空控制器名
75
        'empty_controller'      => 'Error',
76
        // 是否使用控制器后缀
77
        'controller_suffix'     => false,
78
        // 默认路由 [路由规则, 路由地址]
79
        'default_route'         => [],
80
        // 默认模块名
81
        'default_module'        => 'index',
82
        // 默认控制器名
83
        'default_controller'    => 'Index',
84
        // 默认操作名
85
        'default_action'        => 'index',
86
        // 操作方法后缀
87
        'action_suffix'         => '',
88
        // 非路由变量是否使用普通参数方式(用于URL生成)
89
        'url_common_param'      => true,
90
    ];
91
92
    /**
93
     * 请求对象
94
     * @var Request
95
     */
96
    protected $request;
97
98
    /**
99
     * @var RuleName
100
     */
101
    protected $ruleName;
102
103
    /**
104
     * 当前HOST
105
     * @var string
106
     */
107
    protected $host;
108
109
    /**
110
     * 当前分组对象
111
     * @var RuleGroup
112
     */
113
    protected $group;
114
115
    /**
116
     * 域名对象
117
     * @var Domain[]
118
     */
119
    protected $domains = [];
120
121
    /**
122
     * 跨域路由规则
123
     * @var RuleGroup
124
     */
125
    protected $cross;
126
127
    /**
128
     * 路由是否延迟解析
129
     * @var bool
130
     */
131
    protected $lazy = false;
132
133
    /**
134
     * (分组)路由规则是否合并解析
135
     * @var bool
136
     */
137
    protected $mergeRuleRegex = false;
138
139
    /**
140
     * 是否去除URL最后的斜线
141
     * @var bool
142
     */
143
    protected $removeSlash = false;
144
145 27
    public function __construct(protected App $app)
146
    {
147 27
        $this->ruleName = new RuleName();
148 27
        $this->setDefaultDomain();
149
150 27
        if (is_file($this->app->getRuntimePath() . 'route.php')) {
151
            // 读取路由映射文件
152
            $this->import(include $this->app->getRuntimePath() . 'route.php');
153
        }
154
155 27
        $this->config = array_merge($this->config, $this->app->config->get('route'));
0 ignored issues
show
Bug introduced by
It seems like $this->app->config->get('route') can also be of type null; however, parameter $arrays of array_merge() does only seem to accept array, 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

155
        $this->config = array_merge($this->config, /** @scrutinizer ignore-type */ $this->app->config->get('route'));
Loading history...
156
157 27
        $this->init();
158
    }
159
160 27
    protected function init()
161
    {
162 27
        if (!empty($this->config['middleware'])) {
163
            $this->app->middleware->import($this->config['middleware'], 'route');
164
        }
165
166 27
        $this->lazy($this->config['url_lazy_route']);
167 27
        $this->mergeRuleRegex = $this->config['route_rule_merge'];
168 27
        $this->removeSlash    = $this->config['remove_slash'];
169
170 27
        $this->group->removeSlash($this->removeSlash);
171
172
        // 注册全局MISS路由
173 27
        $this->miss(function () {
174 3
            return Response::create('', 'html', 204)->header(['Allow' => 'GET, POST, PUT, DELETE']);
175 27
        }, 'options');
176
    }
177
178 27
    public function config(?string $name = null)
179
    {
180 27
        if (is_null($name)) {
181
            return $this->config;
182
        }
183
184 27
        return $this->config[$name] ?? null;
185
    }
186
187
    /**
188
     * 设置路由域名及分组(包括资源路由)是否延迟解析
189
     * @access public
190
     * @param bool $lazy 路由是否延迟解析
191
     * @return $this
192
     */
193 27
    public function lazy(bool $lazy = true)
194
    {
195 27
        $this->lazy = $lazy;
196 27
        return $this;
197
    }
198
199
    /**
200
     * 设置路由域名及分组(包括资源路由)是否合并解析
201
     * @access public
202
     * @param bool $merge 路由是否合并解析
203
     * @return $this
204
     */
205
    public function mergeRuleRegex(bool $merge = true)
206
    {
207
        $this->mergeRuleRegex = $merge;
208
        $this->group->mergeRuleRegex($merge);
209
210
        return $this;
211
    }
212
213
    /**
214
     * 初始化默认域名
215
     * @access protected
216
     * @return void
217
     */
218 27
    protected function setDefaultDomain(): void
219
    {
220
        // 注册默认域名
221 27
        $domain = new Domain($this);
222
223 27
        $this->domains['-'] = $domain;
224
225
        // 默认分组
226 27
        $this->group = $domain;
227
    }
228
229
    /**
230
     * 设置当前分组
231
     * @access public
232
     * @param RuleGroup $group 域名
233
     * @return void
234
     */
235 27
    public function setGroup(RuleGroup $group): void
236
    {
237 27
        $this->group = $group;
238
    }
239
240
    /**
241
     * 获取指定标识的路由分组 不指定则获取当前分组
242
     * @access public
243
     * @param string $name 分组标识
244
     * @return RuleGroup
245
     */
246 27
    public function getGroup(?string $name = null)
247
    {
248 27
        return $name ? $this->ruleName->getGroup($name) : $this->group;
249
    }
250
251
    /**
252
     * 注册变量规则
253
     * @access public
254
     * @param array $pattern 变量规则
255
     * @return $this
256
     */
257
    public function pattern(array $pattern)
258
    {
259
        $this->group->pattern($pattern);
260
261
        return $this;
262
    }
263
264
    /**
265
     * 注册路由参数
266
     * @access public
267
     * @param array $option 参数
268
     * @return $this
269
     */
270
    public function option(array $option)
271
    {
272
        $this->group->option($option);
273
274
        return $this;
275
    }
276
277
    /**
278
     * 注册域名路由
279
     * @access public
280
     * @param string|array $name 子域名
281
     * @param mixed        $rule 路由规则
282
     * @return Domain
283
     */
284 3
    public function domain(string | array $name, $rule = null): Domain
285
    {
286
        // 支持多个域名使用相同路由规则
287 3
        $domainName = is_array($name) ? array_shift($name) : $name;
0 ignored issues
show
introduced by
The condition is_array($name) is always true.
Loading history...
288
289 3
        if (!isset($this->domains[$domainName])) {
290 3
            $domain = (new Domain($this, $domainName, $rule, $this->lazy))
291 3
                ->removeSlash($this->removeSlash)
292 3
                ->mergeRuleRegex($this->mergeRuleRegex);
293
294 3
            $this->domains[$domainName] = $domain;
295
        } else {
296
            $domain = $this->domains[$domainName];
297
            $domain->parseGroupRule($rule);
298
        }
299
300 3
        if (is_array($name) && !empty($name)) {
301
            foreach ($name as $item) {
302
                $this->domains[$item] = $domainName;
303
            }
304
        }
305
306
        // 返回域名对象
307 3
        return $domain;
308
    }
309
310
    /**
311
     * 获取域名
312
     * @access public
313
     * @return array
314
     */
315
    public function getDomains(): array
316
    {
317
        return $this->domains;
318
    }
319
320
    /**
321
     * 获取域名路由的绑定信息
322
     * @access public
323
     * @param string $domain 子域名
324
     * @return string|null
325
     */
326
    public function getDomainBind(?string $domain = null)
327
    {
328
        if ($domain && isset($this->domains[$domain])) {
329
            $item = $this->domains[$domain];
330
            if (is_string($item)) {
0 ignored issues
show
introduced by
The condition is_string($item) is always false.
Loading history...
331
                $item = $this->domains[$item];
332
            }
333
            return $item->getBind();
334
        }
335
    }
336
337
    /**
338
     * 获取RuleName对象
339
     * @access public
340
     * @return RuleName
341
     */
342
    public function getRuleName(): RuleName
343
    {
344
        return $this->ruleName;
345
    }
346
347
    /**
348
     * 读取路由标识
349
     * @access public
350
     * @param string $name   路由标识
351
     * @param string $domain 域名
352
     * @param string $method 请求类型
353
     * @return array
354
     */
355
    public function getName(?string $name = null, ?string $domain = null, string $method = '*'): array
356
    {
357
        return $this->ruleName->getName($name, $domain, $method);
358
    }
359
360
    /**
361
     * 批量导入路由标识
362
     * @access public
363
     * @param array $name 路由标识
364
     * @return void
365
     */
366
    public function import(array $name): void
367
    {
368
        $this->ruleName->import($name);
369
    }
370
371
    /**
372
     * 注册路由标识
373
     * @access public
374
     * @param string   $name     路由标识
375
     * @param RuleItem $ruleItem 路由规则
376
     * @param bool     $first    是否优先
377
     * @return void
378
     */
379 9
    public function setName(string $name, RuleItem $ruleItem, bool $first = false): void
380
    {
381 9
        $this->ruleName->setName($name, $ruleItem, $first);
382
    }
383
384
    /**
385
     * 保存路由规则
386
     * @access public
387
     * @param string   $rule     路由规则
388
     * @param RuleItem $ruleItem RuleItem对象
389
     * @return void
390
     */
391 27
    public function setRule(string $rule, ?RuleItem $ruleItem = null): void
392
    {
393 27
        $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

393
        $this->ruleName->setRule($rule, /** @scrutinizer ignore-type */ $ruleItem);
Loading history...
394
    }
395
396
    /**
397
     * 读取路由
398
     * @access public
399
     * @param string $rule 路由规则
400
     * @return RuleItem[]
401
     */
402
    public function getRule(string $rule): array
403
    {
404
        return $this->ruleName->getRule($rule);
405
    }
406
407
    /**
408
     * 读取路由列表
409
     * @access public
410
     * @return array
411
     */
412
    public function getRuleList(): array
413
    {
414
        return $this->ruleName->getRuleList();
415
    }
416
417
    /**
418
     * 清空路由规则
419
     * @access public
420
     * @return void
421
     */
422
    public function clear(): void
423
    {
424
        $this->ruleName->clear();
425
426
        if ($this->group) {
427
            $this->group->clear();
428
        }
429
    }
430
431
    /**
432
     * 注册路由规则
433
     * @access public
434
     * @param string $rule   路由规则
435
     * @param mixed  $route  路由地址
436
     * @param string $method 请求类型
437
     * @return RuleItem
438
     */
439 24
    public function rule(string $rule, $route = null, string $method = '*'): RuleItem
440
    {
441 24
        return $this->group->addRule($rule, $route, $method);
442
    }
443
444
    /**
445
     * 设置路由规则全局有效
446
     * @access public
447
     * @param Rule   $rule   路由规则
448
     * @return $this
449
     */
450
    public function setCrossDomainRule(Rule $rule)
451
    {
452
        if (!isset($this->cross)) {
453
            $this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex);
454
        }
455
456
        $this->cross->addRuleItem($rule);
457
458
        return $this;
459
    }
460
461
    /**
462
     * 注册路由分组
463
     * @access public
464
     * @param string|Closure $name  分组名称或者参数
465
     * @param mixed           $route 分组路由
466
     * @return RuleGroup
467
     */
468 3
    public function group(string | Closure $name, $route = null): RuleGroup
469
    {
470 3
        if ($name instanceof Closure) {
471 3
            $route = $name;
472 3
            $name  = '';
473
        }
474
475 3
        return (new RuleGroup($this, $this->group, $name, $route, $this->lazy))
476 3
            ->removeSlash($this->removeSlash)
477 3
            ->mergeRuleRegex($this->mergeRuleRegex);
478
    }
479
480
    /**
481
     * 注册路由
482
     * @access public
483
     * @param string $rule  路由规则
484
     * @param mixed  $route 路由地址
485
     * @return RuleItem
486
     */
487
    public function any(string $rule, $route): RuleItem
488
    {
489
        return $this->rule($rule, $route, '*');
490
    }
491
492
    /**
493
     * 注册GET路由
494
     * @access public
495
     * @param string $rule  路由规则
496
     * @param mixed  $route 路由地址
497
     * @return RuleItem
498
     */
499 18
    public function get(string $rule, $route): RuleItem
500
    {
501 18
        return $this->rule($rule, $route, 'GET');
502
    }
503
504
    /**
505
     * 注册POST路由
506
     * @access public
507
     * @param string $rule  路由规则
508
     * @param mixed  $route 路由地址
509
     * @return RuleItem
510
     */
511 3
    public function post(string $rule, $route): RuleItem
512
    {
513 3
        return $this->rule($rule, $route, 'POST');
514
    }
515
516
    /**
517
     * 注册PUT路由
518
     * @access public
519
     * @param string $rule  路由规则
520
     * @param mixed  $route 路由地址
521
     * @return RuleItem
522
     */
523 3
    public function put(string $rule, $route): RuleItem
524
    {
525 3
        return $this->rule($rule, $route, 'PUT');
526
    }
527
528
    /**
529
     * 注册DELETE路由
530
     * @access public
531
     * @param string $rule  路由规则
532
     * @param mixed  $route 路由地址
533
     * @return RuleItem
534
     */
535
    public function delete(string $rule, $route): RuleItem
536
    {
537
        return $this->rule($rule, $route, 'DELETE');
538
    }
539
540
    /**
541
     * 注册PATCH路由
542
     * @access public
543
     * @param string $rule  路由规则
544
     * @param mixed  $route 路由地址
545
     * @return RuleItem
546
     */
547
    public function patch(string $rule, $route): RuleItem
548
    {
549
        return $this->rule($rule, $route, 'PATCH');
550
    }
551
552
    /**
553
     * 注册HEAD路由
554
     * @access public
555
     * @param string $rule  路由规则
556
     * @param mixed  $route 路由地址
557
     * @return RuleItem
558
     */
559
    public function head(string $rule, $route): RuleItem
560
    {
561
        return $this->rule($rule, $route, 'HEAD');
562
    }
563
564
    /**
565
     * 注册OPTIONS路由
566
     * @access public
567
     * @param string $rule  路由规则
568
     * @param mixed  $route 路由地址
569
     * @return RuleItem
570
     */
571
    public function options(string $rule, $route): RuleItem
572
    {
573
        return $this->rule($rule, $route, 'OPTIONS');
574
    }
575
576
    /**
577
     * 注册资源路由
578
     * @access public
579
     * @param string $rule  路由规则
580
     * @param string $route 路由地址
581
     * @return Resource|ResourceRegister
582
     */
583
    public function resource(string $rule, string $route)
584
    {
585
        $resource = new Resource($this, $this->group, $rule, $route, $this->rest);
586
587
        if (!$this->lazy) {
588
            return new ResourceRegister($resource);
589
        }
590
591
        return $resource;
592
    }
593
594
    /**
595
     * 注册视图路由
596
     * @access public
597
     * @param string $rule     路由规则
598
     * @param string $template 路由模板地址
599
     * @param array  $vars     模板变量
600
     * @return RuleItem
601
     */
602 3
    public function view(string $rule, string $template = '', array $vars = []): RuleItem
603
    {
604 3
        return $this->rule($rule, function () use ($vars, $template) {
605 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

605
            return Response::create($template, 'view')->/** @scrutinizer ignore-call */ assign($vars);
Loading history...
606 3
        }, 'GET');
607
    }
608
609
    /**
610
     * 注册重定向路由
611
     * @access public
612
     * @param string $rule   路由规则
613
     * @param string $route  路由地址
614
     * @param int    $status 状态码
615
     * @return RuleItem
616
     */
617 3
    public function redirect(string $rule, string $route = '', int $status = 301): RuleItem
618
    {
619 3
        return $this->rule($rule, function (Request $request) use ($status, $route) {
620 3
            $search  = $replace  = [];
621 3
            $matches = $request->rule()->getVars();
622
623 3
            foreach ($matches as $key => $value) {
624
                $search[]  = '<' . $key . '>';
625
                $replace[] = $value;
626
                $search[]  = '{' . $key . '}';
627
                $replace[] = $value;
628
                $search[]  = ':' . $key;
629
                $replace[] = $value;
630
            }
631
632 3
            $route = str_replace($search, $replace, $route);
633 3
            return Response::create($route, 'redirect')->code($status);
634 3
        }, '*');
635
    }
636
637
    /**
638
     * rest方法定义和修改
639
     * @access public
640
     * @param string|array $name     方法名称
641
     * @param array|bool   $resource 资源
642
     * @return $this
643
     */
644
    public function rest(string | array $name, array | bool $resource = [])
645
    {
646
        if (is_array($name)) {
0 ignored issues
show
introduced by
The condition is_array($name) is always true.
Loading history...
647
            $this->rest = $resource ? $name : array_merge($this->rest, $name);
648
        } else {
649
            $this->rest[$name] = $resource;
650
        }
651
652
        return $this;
653
    }
654
655
    /**
656
     * 获取rest方法定义的参数
657
     * @access public
658
     * @param string $name 方法名称
659
     * @return array|null
660
     */
661
    public function getRest(?string $name = null)
662
    {
663
        if (is_null($name)) {
664
            return $this->rest;
665
        }
666
667
        return $this->rest[$name] ?? null;
668
    }
669
670
    /**
671
     * 注册未匹配路由规则后的处理
672
     * @access public
673
     * @param string|Closure $route  路由地址
674
     * @param string         $method 请求类型
675
     * @return RuleItem
676
     */
677 27
    public function miss(string | Closure $route, string $method = '*'): RuleItem
678
    {
679 27
        return $this->group->miss($route, $method);
680
    }
681
682
    /**
683
     * 路由调度
684
     * @param Request $request
685
     * @param Closure|bool $withRoute
686
     * @return Response
687
     */
688 27
    public function dispatch(Request $request, Closure | bool $withRoute = true)
689
    {
690 27
        $this->request = $request;
691 27
        $this->host    = $this->request->host(true);
692 27
        $completeMatch = (bool) $this->config['route_complete_match'];
693 27
        $url           = str_replace($this->config['pathinfo_depr'], '|', $this->path());
694
695 27
        if ($withRoute) {
696 27
            if ($withRoute instanceof Closure) {
697
                $withRoute();
698
            }
699
            // 路由检测
700 27
            $dispatch = $this->check($url, $completeMatch);
701
        }
702
703 27
        if (empty($dispatch)) {
704
            // 默认URL调度
705 3
            $dispatch = $this->checkUrlDispatch($url);
706
        }
707
708 27
        $dispatch->init($this->app);
709
710 27
        return $this->app->middleware->pipeline('route')
711 27
            ->send($request)
712 27
            ->then(function () use ($dispatch) {
713 27
                return $dispatch->run();
714 27
            });
715
    }
716
717
    /**
718
     * 检测URL路由
719
     * @access public
720
     * @param  bool $completeMatch
721
     * @return Dispatch|false
722
     * @throws RouteNotFoundException
723
     */
724 27
    public function check(string $url, bool $completeMatch = false)
725
    {
726
        // 检测域名路由
727 27
        $result = $this->checkDomain()->check($this->request, $url, $completeMatch);
728
729 27
        if (false === $result && !empty($this->cross)) {
730
            // 检测跨域路由
731
            $result = $this->cross->check($this->request, $url, $completeMatch);
732
        }
733
734 27
        if (false === $result && $this->config['url_route_must']) {
735
            // 开启强制路由
736
            throw new RouteNotFoundException();
737
        }
738
739 27
        return $result;
740
    }
741
742
    /**
743
     * 获取当前请求URL的pathinfo信息(不含URL后缀)
744
     * @access protected
745
     * @return string
746
     */
747 27
    protected function path(): string
748
    {
749 27
        $suffix   = $this->config['url_html_suffix'];
750 27
        $pathinfo = $this->request->pathinfo();
751
752 27
        if (false === $suffix) {
753
            // 禁止伪静态访问
754
            $path = $pathinfo;
755 27
        } elseif ($suffix) {
756
            // 去除正常的URL后缀
757 27
            $path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
758
        } else {
759
            // 允许任何后缀访问
760
            $path = preg_replace('/\.' . $this->request->ext() . '$/i', '', $pathinfo);
761
        }
762
763 27
        return $path;
764
    }
765
766
    /**
767
     * 自动多模块URL路由 如使用多模块在路由定义文件最后定义
768
     * @access public
769
     * @param  string $rule    路由规则
770
     * @param  mixed  $route   路由地址
771
     * @return RuleItem
772
     */
773
    public function auto(string $rule = '[:module]/[:controller]/[:action]', $route = ':module/:controller/:action'): RuleItem
774
    {
775
        return $this->rule($rule, $route)
776
            ->pattern([
777
                'module'     => '[A-Za-z0-9\.\_]+',
778
                'controller' => '[A-Za-z0-9\.\_]+',
779
                'action'     => '[A-Za-z0-9\_]+',
780
            ])->default([
781
                'module'     => $this->config['default_module'],
782
                'controller' => $this->config['default_controller'],
783
                'action'     => $this->config['default_action'],
784
            ]);
785
    }
786
787
    /**
788
     * 检测默认URL解析路由
789
     * @access public
790
     * @param  string   $url URL
791
     * @return Dispatch
792
     */
793 3
    protected function checkUrlDispatch(string $url): Dispatch
794
    {
795 3
        return $this->group->auto()->checkBind($this->request, $url);
796
    }
797
798
    /**
799
     * 检测域名的路由规则
800
     * @access protected
801
     * @return Domain
802
     */
803 27
    protected function checkDomain(): Domain
804
    {
805 27
        $item = false;
806
807 27
        if (count($this->domains) > 1) {
808
            // 获取当前子域名
809 3
            $subDomain = $this->request->subDomain();
810 3
            $domain    = $subDomain ? explode('.', $subDomain) : [];
811 3
            $domain2   = $domain ? array_pop($domain) : '';
812
813 3
            if ($domain) {
814
                // 存在三级域名
815
                $domain3 = array_pop($domain);
816
            }
817
818 3
            if (isset($this->domains[$this->host])) {
819
                // 子域名配置
820
                $item = $this->domains[$this->host];
821 3
            } elseif (isset($this->domains[$subDomain])) {
822 3
                $item = $this->domains[$subDomain];
823
            } elseif (isset($this->domains['*.' . $domain2]) && !empty($domain3)) {
824
                // 泛三级域名
825
                $item      = $this->domains['*.' . $domain2];
826
                $panDomain = $domain3;
827
            } elseif (isset($this->domains['*']) && !empty($domain2)) {
828
                // 泛二级域名
829
                if ('www' != $domain2) {
830
                    $item      = $this->domains['*'];
831
                    $panDomain = $domain2;
832
                }
833
            }
834
835 3
            if (isset($panDomain)) {
836
                // 保存当前泛域名
837
                $this->request->setPanDomain($panDomain);
838
            }
839
        }
840
841 27
        if (false === $item) {
842
            // 检测全局域名规则
843 24
            $item = $this->domains['-'];
844
        }
845
846 27
        if (is_string($item)) {
847
            $item = $this->domains[$item];
848
        }
849
850 27
        return $item;
851
    }
852
853
    /**
854
     * URL生成 支持路由反射
855
     * @access public
856
     * @param string $url  路由地址
857
     * @param array  $vars 参数 ['a'=>'val1', 'b'=>'val2']
858
     * @return UrlBuild
859
     */
860
    public function buildUrl(string $url = '', array $vars = []): UrlBuild
861
    {
862
        return $this->app->make(UrlBuild::class, [$this, $this->app, $url, $vars], true);
863
    }
864
865
    /**
866
     * 设置全局的路由分组参数
867
     * @access public
868
     * @param string $method 方法名
869
     * @param array  $args   调用参数
870
     * @return RuleGroup
871
     */
872
    public function __call($method, $args)
873
    {
874
        return call_user_func_array([$this->group, $method], $args);
875
    }
876
}
877