Completed
Push — 6.0 ( a75685...8c1faf )
by liu
06:09
created

Route::patch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

473
        $this->ruleName->setRule($rule, /** @scrutinizer ignore-type */ $ruleItem);
Loading history...
474
    }
475
476
    /**
477
     * 读取路由
478
     * @access public
479
     * @param string $rule 路由规则
480
     * @return RuleItem[]
481
     */
482
    public function getRule(string $rule): array
483
    {
484
        return $this->ruleName->getRule($rule);
485
    }
486
487
    /**
488
     * 读取路由列表
489
     * @access public
490
     * @return array
491
     */
492
    public function getRuleList(): array
493
    {
494
        return $this->ruleName->getRuleList();
495
    }
496
497
    /**
498
     * 清空路由规则
499
     * @access public
500
     * @return void
501
     */
502
    public function clear(): void
503
    {
504
        $this->ruleName->clear();
505
506
        if ($this->group) {
507
            $this->group->clear();
508
        }
509
    }
510
511
    /**
512
     * 注册路由规则
513
     * @access public
514
     * @param string $rule   路由规则
515
     * @param mixed  $route  路由地址
516
     * @param string $method 请求类型
517
     * @return RuleItem
518
     */
519
    public function rule(string $rule, $route = null, string $method = '*'): RuleItem
520
    {
521
        return $this->group->addRule($rule, $route, $method);
522
    }
523
524
    /**
525
     * 设置跨域有效路由规则
526
     * @access public
527
     * @param Rule   $rule   路由规则
528
     * @param string $method 请求类型
529
     * @return $this
530
     */
531
    public function setCrossDomainRule(Rule $rule, string $method = '*')
532
    {
533
        if (!isset($this->cross)) {
534
            $this->cross = (new RuleGroup($this))->mergeRuleRegex($this->mergeRuleRegex);
535
        }
536
537
        $this->cross->addRuleItem($rule, $method);
538
539
        return $this;
540
    }
541
542
    /**
543
     * 注册应用路由
544
     * @access public
545
     * @param string  $name  应用名称
546
     * @param Closure $route 应用路由
547
     * @return RuleGroup
548
     */
549
    public function app($name, Closure $route): RuleGroup
550
    {
551
        return $this->group('', $route)->app($name);
552
    }
553
554
    /**
555
     * 注册路由分组
556
     * @access public
557
     * @param string|\Closure $name  分组名称或者参数
558
     * @param mixed           $route 分组路由
559
     * @return RuleGroup
560
     */
561
    public function group($name, $route = null): RuleGroup
562
    {
563
        if ($name instanceof Closure) {
564
            $route = $name;
565
            $name  = '';
566
        }
567
568
        return (new RuleGroup($this, $this->group, $name, $route))
569
            ->lazy($this->lazy)
570
            ->removeSlash($this->removeSlash)
571
            ->mergeRuleRegex($this->mergeRuleRegex);
572
    }
573
574
    /**
575
     * 注册路由
576
     * @access public
577
     * @param string $rule  路由规则
578
     * @param mixed  $route 路由地址
579
     * @return RuleItem
580
     */
581
    public function any(string $rule, $route): RuleItem
582
    {
583
        return $this->rule($rule, $route, '*');
584
    }
585
586
    /**
587
     * 注册GET路由
588
     * @access public
589
     * @param string $rule  路由规则
590
     * @param mixed  $route 路由地址
591
     * @return RuleItem
592
     */
593
    public function get(string $rule, $route): RuleItem
594
    {
595
        return $this->rule($rule, $route, 'GET');
596
    }
597
598
    /**
599
     * 注册POST路由
600
     * @access public
601
     * @param string $rule  路由规则
602
     * @param mixed  $route 路由地址
603
     * @return RuleItem
604
     */
605
    public function post(string $rule, $route): RuleItem
606
    {
607
        return $this->rule($rule, $route, 'POST');
608
    }
609
610
    /**
611
     * 注册PUT路由
612
     * @access public
613
     * @param string $rule  路由规则
614
     * @param mixed  $route 路由地址
615
     * @return RuleItem
616
     */
617
    public function put(string $rule, $route): RuleItem
618
    {
619
        return $this->rule($rule, $route, 'PUT');
620
    }
621
622
    /**
623
     * 注册DELETE路由
624
     * @access public
625
     * @param string $rule  路由规则
626
     * @param mixed  $route 路由地址
627
     * @return RuleItem
628
     */
629
    public function delete(string $rule, $route): RuleItem
630
    {
631
        return $this->rule($rule, $route, 'DELETE');
632
    }
633
634
    /**
635
     * 注册PATCH路由
636
     * @access public
637
     * @param string $rule  路由规则
638
     * @param mixed  $route 路由地址
639
     * @return RuleItem
640
     */
641
    public function patch(string $rule, $route): RuleItem
642
    {
643
        return $this->rule($rule, $route, 'PATCH');
644
    }
645
646
    /**
647
     * 注册OPTIONS路由
648
     * @access public
649
     * @param string $rule  路由规则
650
     * @param mixed  $route 路由地址
651
     * @return RuleItem
652
     */
653
    public function options(string $rule, $route): RuleItem
654
    {
655
        return $this->rule($rule, $route, 'OPTIONS');
656
    }
657
658
    /**
659
     * 注册资源路由
660
     * @access public
661
     * @param string $rule  路由规则
662
     * @param string $route 路由地址
663
     * @return Resource
664
     */
665
    public function resource(string $rule, string $route): Resource
666
    {
667
        return (new Resource($this, $this->group, $rule, $route, $this->rest))
668
            ->lazy($this->lazy);
669
    }
670
671
    /**
672
     * 注册视图路由
673
     * @access public
674
     * @param string $rule     路由规则
675
     * @param string $template 路由模板地址
676
     * @param array  $vars     模板变量
677
     * @return RuleItem
678
     */
679
    public function view(string $rule, string $template = '', array $vars = []): RuleItem
680
    {
681
        return $this->rule($rule, $template, 'GET')->view($vars);
682
    }
683
684
    /**
685
     * 注册重定向路由
686
     * @access public
687
     * @param string $rule   路由规则
688
     * @param string $route  路由地址
689
     * @param int    $status 状态码
690
     * @return RuleItem
691
     */
692
    public function redirect(string $rule, string $route = '', int $status = 301): RuleItem
693
    {
694
        return $this->rule($rule, $route, '*')->redirect()->status($status);
695
    }
696
697
    /**
698
     * rest方法定义和修改
0 ignored issues
show
Coding Style introduced by
Doc comment short description must start with a capital letter
Loading history...
699
     * @access public
700
     * @param string|array $name     方法名称
701
     * @param array|bool   $resource 资源
702
     * @return $this
703
     */
704
    public function rest($name, $resource = [])
705
    {
706
        if (is_array($name)) {
707
            $this->rest = $resource ? $name : array_merge($this->rest, $name);
708
        } else {
709
            $this->rest[$name] = $resource;
710
        }
711
712
        return $this;
713
    }
714
715
    /**
716
     * 获取rest方法定义的参数
717
     * @access public
718
     * @param string $name 方法名称
719
     * @return array|null
720
     */
721
    public function getRest(string $name = null)
722
    {
723
        if (is_null($name)) {
724
            return $this->rest;
725
        }
726
727
        return $this->rest[$name] ?? null;
728
    }
729
730
    /**
731
     * 注册未匹配路由规则后的处理
732
     * @access public
733
     * @param string|Closure $route  路由地址
734
     * @param string         $method 请求类型
735
     * @return RuleItem
736
     */
737
    public function miss($route, string $method = '*'): RuleItem
738
    {
739
        return $this->group->miss($route, $method);
740
    }
741
742
    /**
743
     * 路由调度
744
     * @param Request $request
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
745
     * @param Closure $withRoute
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
746
     * @return Response
747
     */
748
    public function dispatch(Request $request, $withRoute = null)
749
    {
750
        $this->request = $request;
751
        $this->host    = $this->request->host(true);
752
        $this->init();
753
754
        return $this->app->middleware->pipeline()
755
            ->send($request)
756
            ->then(function ($request) use ($withRoute) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
757
                if ($withRoute) {
758
                    $checkCallback = function () use ($withRoute) {
759
                        //加载路由
760
                        $withRoute();
761
                        return $this->check();
762
                    };
763
764
                    if ($this->config['route_check_cache']) {
765
                        $dispatch = $this->cache
766
                            ->tag('route_cache')
767
                            ->remember($this->getRouteCacheKey($request), $checkCallback);
768
                    } else {
769
                        $dispatch = $checkCallback();
770
                    }
771
                } else {
772
                    $dispatch = $this->url($this->path());
773
                }
774
775
                $dispatch->init($this->app);
776
777
                return $dispatch->run();
778
            });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
779
    }
780
781
    /**
782
     * 获取路由缓存Key
783
     * @access protected
784
     * @param Request $request
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
785
     * @return string
786
     */
787
    protected function getRouteCacheKey(Request $request): string
788
    {
789
        if (!empty($this->config['route_check_cache_key'])) {
790
            $closure  = $this->config['route_check_cache_key'];
791
            $routeKey = $closure($request);
792
        } else {
793
            $routeKey = md5($request->baseUrl(true) . ':' . $request->method());
794
        }
795
796
        return $routeKey;
797
    }
798
799
    /**
800
     * 检测URL路由
801
     * @access public
802
     * @return Dispatch
803
     * @throws RouteNotFoundException
804
     */
805
    public function check(): Dispatch
806
    {
807
        // 自动检测域名路由
808
        $url = str_replace($this->config['pathinfo_depr'], '|', $this->path());
809
810
        $completeMatch = $this->config['route_complete_match'];
811
812
        $result = $this->checkDomain()->check($this->request, $url, $completeMatch);
813
814
        if (false === $result && !empty($this->cross)) {
815
            // 检测跨域路由
816
            $result = $this->cross->check($this->request, $url, $completeMatch);
817
        }
818
819
        if (false !== $result) {
820
            return $result;
821
        } elseif ($this->config['url_route_must']) {
822
            throw new RouteNotFoundException();
823
        }
824
825
        return $this->url($url);
826
    }
827
828
    /**
829
     * 获取当前请求URL的pathinfo信息(不含URL后缀)
830
     * @access protected
831
     * @return string
832
     */
833
    protected function path(): string
834
    {
835
        $suffix   = $this->config['url_html_suffix'];
836
        $pathinfo = $this->request->pathinfo();
837
838
        if (false === $suffix) {
839
            // 禁止伪静态访问
840
            $path = $pathinfo;
841
        } elseif ($suffix) {
842
            // 去除正常的URL后缀
843
            $path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
844
        } else {
845
            // 允许任何后缀访问
846
            $path = preg_replace('/\.' . $this->request->ext() . '$/i', '', $pathinfo);
847
        }
848
849
        return $path;
850
    }
851
852
    /**
853
     * 默认URL解析
854
     * @access public
855
     * @param string $url URL地址
856
     * @return Dispatch
857
     */
858
    public function url(string $url): UrlDispatch
859
    {
860
        if ($this->app->http->isMulti() && $this->config['cross_app_route']) {
861
            if ('' === $url) {
862
                $this->app->http->setApp($this->app->config->get('app.default_app', 'index'));
0 ignored issues
show
Bug introduced by
It seems like $this->app->config->get(....default_app', 'index') can also be of type array; however, parameter $appName of think\Http::setApp() does only seem to accept string, 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

862
                $this->app->http->setApp(/** @scrutinizer ignore-type */ $this->app->config->get('app.default_app', 'index'));
Loading history...
863
            } else {
864
                $array = explode('|', $url);
865
                $this->app->http->setApp(array_shift($array));
866
                $url = implode('|', $array);
867
            }
868
        }
869
870
        return new UrlDispatch($this->request, $this->group, $url);
871
    }
872
873
    /**
874
     * 检测域名的路由规则
875
     * @access protected
876
     * @return Domain
877
     */
878
    protected function checkDomain(): Domain
879
    {
880
        $item = false;
881
882
        if (count($this->domains) > 1) {
883
            // 获取当前子域名
884
            $subDomain = $this->request->subDomain();
885
886
            $domain  = $subDomain ? explode('.', $subDomain) : [];
887
            $domain2 = $domain ? array_pop($domain) : '';
888
889
            if ($domain) {
890
                // 存在三级域名
891
                $domain3 = array_pop($domain);
892
            }
893
894
            if (isset($this->domains[$this->host])) {
895
                // 子域名配置
896
                $item = $this->domains[$this->host];
897
            } elseif (isset($this->domains[$subDomain])) {
898
                $item = $this->domains[$subDomain];
899
            } elseif (isset($this->domains['*.' . $domain2]) && !empty($domain3)) {
900
                // 泛三级域名
901
                $item      = $this->domains['*.' . $domain2];
902
                $panDomain = $domain3;
903
            } elseif (isset($this->domains['*']) && !empty($domain2)) {
904
                // 泛二级域名
905
                if ('www' != $domain2) {
906
                    $item      = $this->domains['*'];
907
                    $panDomain = $domain2;
908
                }
909
            }
910
911
            if (isset($panDomain)) {
912
                // 保存当前泛域名
913
                $this->request->setPanDomain($panDomain);
914
            }
915
        }
916
917
        if (false === $item) {
918
            // 检测全局域名规则
919
            $item = $this->domains['-'];
920
        }
921
922
        if (is_string($item)) {
923
            $item = $this->domains[$item];
924
        }
925
926
        return $item;
927
    }
928
929
    /**
930
     * URL生成 支持路由反射
931
     * @access public
932
     * @param string $url  路由地址
933
     * @param array  $vars 参数 ['a'=>'val1', 'b'=>'val2']
934
     * @return UrlBuild
935
     */
936
    public function buildUrl(string $url = '', array $vars = []): UrlBuild
937
    {
938
        return new UrlBuild($this, $this->app, $url, $vars);
939
    }
940
941
    /**
942
     * 设置全局的路由分组参数
943
     * @access public
944
     * @param string $method 方法名
945
     * @param array  $args   调用参数
946
     * @return RuleGroup
947
     */
948
    public function __call($method, $args)
949
    {
950
        return call_user_func_array([$this->group, $method], $args);
951
    }
952
}
953