Completed
Push — 6.0 ( cb9c04...e3fbef )
by liu
03:49
created

CheckRequestCache::getRequestCache()   C

Complexity

Conditions 15
Paths 114

Size

Total Lines 53
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 0
Metric Value
cc 15
eloc 30
nc 114
nop 1
dl 0
loc 53
ccs 0
cts 30
cp 0
crap 240
rs 5.8
c 0
b 0
f 0

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
// +----------------------------------------------------------------------
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\middleware;
14
15
use Closure;
16
use think\Cache;
17
use think\Config;
18
use think\Request;
19
use think\Response;
20
21
/**
22
 * 请求缓存处理
23
 */
5 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
24
class CheckRequestCache
25
{
26
    /**
27
     * 缓存对象
28
     * @var Cache
29
     */
30
    protected $cache;
31
32
    /**
33
     * 配置参数
34
     * @var array
35
     */
36
    protected $config = [
37
        // 请求缓存规则 true为自动规则
38
        'request_cache_key'    => true,
39
        // 请求缓存有效期
40
        'request_cache_expire' => null,
41
        // 全局请求缓存排除规则
42
        'request_cache_except' => [],
43
        // 请求缓存的Tag
44
        'request_cache_tag'    => '',
45
    ];
46
47
    public function __construct(Cache $cache, Config $config)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
48
    {
49
        $this->cache  = $cache;
50
        $this->config = array_merge($this->config, $config->get('route'));
51
    }
52
53
    /**
54
     * 设置当前地址的请求缓存
55
     * @access public
56
     * @param Request $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
57
     * @param Closure $next
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
58
     * @param mixed   $cache
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
59
     * @return Response
60
     */
61
    public function handle($request, Closure $next, $cache = null)
62
    {
63
        if ($request->isGet() && false !== $cache) {
64
            $cache = $cache ?: $this->getRequestCache();
0 ignored issues
show
Bug introduced by
The call to think\middleware\CheckRe...ache::getRequestCache() has too few arguments starting with request. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

64
            $cache = $cache ?: $this->/** @scrutinizer ignore-call */ getRequestCache();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
65
66
            if ($cache) {
67
                if (is_array($cache)) {
68
                    list($key, $expire, $tag) = $cache;
69
                } else {
70
                    $key    = str_replace('|', '/', $request->url());
71
                    $expire = $cache;
72
                    $tag    = null;
73
                }
74
75
                if (strtotime($request->server('HTTP_IF_MODIFIED_SINCE', '')) + $expire > $request->server('REQUEST_TIME')) {
76
                    // 读取缓存
77
                    return Response::create()->code(304);
78
                } elseif ($this->cache->has($key)) {
79
                    list($content, $header) = $this->cache->get($key);
80
81
                    return Response::create($content)->header($header);
82
                }
83
            }
84
        }
85
86
        $response = $next($request);
87
88
        if (isset($key) && 200 == $response->getCode() && $response->isAllowCache()) {
89
            $header                  = $response->getHeader();
90
            $header['Cache-Control'] = 'max-age=' . $expire . ',must-revalidate';
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $expire does not seem to be defined for all execution paths leading up to this point.
Loading history...
91
            $header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';
92
            $header['Expires']       = gmdate('D, d M Y H:i:s', time() + $expire) . ' GMT';
93
94
            $this->cache->tag($tag)->set($key, [$response->getContent(), $header], $expire);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tag does not seem to be defined for all execution paths leading up to this point.
Loading history...
95
        }
96
97
        return $response;
98
    }
99
100
    /**
101
     * 读取当前地址的请求缓存信息
102
     * @access protected
103
     * @param Request $request
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
104
     * @return mixed
105
     */
106
    protected function getRequestCache($request)
107
    {
108
        $key    = $this->config['request_cache_key'];
109
        $expire = $this->config['request_cache_expire'];
110
        $except = $this->config['request_cache_except'];
111
        $tag    = $this->config['request_cache_tag'];
112
113
        if (false === $key) {
114
            // 关闭当前缓存
115
            return;
116
        }
117
118
        foreach ($except as $rule) {
119
            if (0 === stripos($request->url(), $rule)) {
120
                return;
121
            }
122
        }
123
124
        if ($key instanceof \Closure) {
125
            $key = call_user_func($key);
126
        } elseif (true === $key) {
127
            // 自动缓存功能
128
            $key = '__URL__';
129
        } elseif (strpos($key, '|')) {
130
            list($key, $fun) = explode('|', $key);
131
        }
132
133
        // 特殊规则替换
134
        if (false !== strpos($key, '__')) {
135
            $key = str_replace(['__APP__', '__CONTROLLER__', '__ACTION__', '__URL__'], [$request->app(), $request->controller(), $request->action(), md5($request->url(true))], $key);
136
        }
137
138
        if (false !== strpos($key, ':')) {
139
            $param = $request->param();
140
            foreach ($param as $item => $val) {
141
                if (is_string($val) && false !== strpos($key, ':' . $item)) {
142
                    $key = str_replace(':' . $item, $val, $key);
143
                }
144
            }
145
        } elseif (strpos($key, ']')) {
146
            if ('[' . $request->ext() . ']' == $key) {
147
                // 缓存某个后缀的请求
148
                $key = md5($request->url());
149
            } else {
150
                return;
151
            }
152
        }
153
154
        if (isset($fun)) {
155
            $key = $fun($key);
156
        }
157
158
        return [$key, $expire, $tag];
159
    }
160
}
161