Passed
Push — 5.2 ( 94f706...1b9ee1 )
by liu
03:53
created

Url   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 92
rs 10
c 0
b 0
f 0
wmc 16

3 Methods

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