Completed
Push — 6.0 ( d30585...7d6f90 )
by yun
02:09
created

Url::parseUrl()   C

Complexity

Conditions 13
Paths 105

Size

Total Lines 51
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 18.5377

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 13
eloc 25
c 2
b 0
f 0
nc 105
nop 1
dl 0
loc 51
ccs 17
cts 25
cp 0.68
crap 18.5377
rs 6.575

How to fix   Long Method    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\route\dispatch;
14
15
use think\exception\HttpException;
16
use think\helper\Str;
17
use think\Request;
18
use think\route\Rule;
19
20
/**
21
 * Url Dispatcher
22
 */
23
class Url extends Controller
24
{
25
26 3
    public function __construct(Request $request, Rule $rule, $dispatch, array $param = [], int $code = null)
27
    {
28 3
        $this->request = $request;
29 3
        $this->rule    = $rule;
30
        // 解析默认的URL规则
31 3
        $dispatch = $this->parseUrl($dispatch);
32
33 3
        parent::__construct($request, $rule, $dispatch, $this->param, $code);
34 3
    }
35
36
    /**
37
     * 解析URL地址
38
     * @access protected
39
     * @param  string $url URL
40
     * @return array
41
     */
42 3
    protected function parseUrl(string $url): array
43
    {
44 3
        $depr = $this->rule->config('pathinfo_depr');
45 3
        $bind = $this->rule->getRouter()->getDomainBind();
46
47 3
        if ($bind && preg_match('/^[a-z]/is', $bind)) {
48
            $bind = str_replace('/', $depr, $bind);
49
            // 如果有域名绑定
50
            $url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr);
51
        }
52
53 3
        $path = $this->rule->parseUrlPath($url);
54 3
        if (empty($path)) {
55
            return [null, null];
56
        }
57
58
        // 解析控制器
59 3
        $controller = !empty($path) ? array_shift($path) : null;
60
61 3
        if ($controller && !preg_match('/^[A-Za-z0-9][\w|\.]*$/', $controller)) {
62
            throw new HttpException(404, 'controller not exists:' . $controller);
63
        }
64
65
        // 解析操作
66 3
        $action = !empty($path) ? array_shift($path) : null;
67 3
        $var    = [];
68
69
        // 解析额外参数
70 3
        if ($path) {
71
            preg_replace_callback('/(\w+)\|([^\|]+)/', function ($match) use (&$var) {
72
                $var[$match[1]] = strip_tags($match[2]);
73
            }, implode('|', $path));
74
        }
75
76 3
        $panDomain = $this->request->panDomain();
77 3
        if ($panDomain && $key = array_search('*', $var)) {
78
            // 泛域名赋值
79
            $var[$key] = $panDomain;
80
        }
81
82
        // 设置当前请求的参数
83 3
        $this->param = $var;
84
85
        // 封装路由
86 3
        $route = [$controller, $action];
87
88 3
        if ($this->hasDefinedRoute($route)) {
89
            throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url));
90
        }
91
92 3
        return $route;
93
    }
94
95
    /**
96
     * 检查URL是否已经定义过路由
97
     * @access protected
98
     * @param  array $route 路由信息
99
     * @return bool
100
     */
101 3
    protected function hasDefinedRoute(array $route): bool
102
    {
103 3
        [$controller, $action] = $route;
104
105
        // 检查地址是否被定义过路由
106 3
        $name = strtolower(Str::studly($controller) . '/' . $action);
107
108 3
        $host   = $this->request->host(true);
109 3
        $method = $this->request->method();
110
111 3
        if ($this->rule->getRouter()->getName($name, $host, $method)) {
112
            return true;
113
        }
114
115 3
        return false;
116
    }
117
118
}
119