Completed
Push — 6.0 ( 6d384e...8d084d )
by liu
11:11 queued 04:03
created

CheckRequestCache::handle()   C

Complexity

Conditions 13
Paths 16

Size

Total Lines 38
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 13
eloc 23
c 4
b 0
f 0
nc 16
nop 3
dl 0
loc 38
ccs 0
cts 23
cp 0
crap 182
rs 6.6166

How to fix   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\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
 */
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
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
57
     * @param Closure $next
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
58
     * @param mixed   $cache
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
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($request);
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 (($hit = $this->cache->get($key)) !== null) {
79
                    list($content, $header, $when) = $hit;
80
                    if ($expire === null || $when + $expire > $request->server('REQUEST_TIME')) {
81
                        return Response::create($content)->header($header);
82
                    }
83
                }
84
            }
85
        }
86
87
        $response = $next($request);
88
89
        if (isset($key) && 200 == $response->getCode() && $response->isAllowCache()) {
90
            $header                  = $response->getHeader();
91
            $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...
92
            $header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';
93
            $header['Expires']       = gmdate('D, d M Y H:i:s', time() + $expire) . ' GMT';
94
95
            $this->cache->tag($tag)->set($key, [$response->getContent(), $header, time()], $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...
96
        }
97
98
        return $response;
99
    }
100
101
    /**
102
     * 读取当前地址的请求缓存信息
103
     * @access protected
104
     * @param Request $request
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
105
     * @return mixed
106
     */
107
    protected function getRequestCache($request)
108
    {
109
        $key    = $this->config['request_cache_key'];
110
        $expire = $this->config['request_cache_expire'];
111
        $except = $this->config['request_cache_except'];
112
        $tag    = $this->config['request_cache_tag'];
113
114
        if ($key instanceof \Closure) {
115
            $key = call_user_func($key, $request);
116
        }
117
118
        if (false === $key) {
119
            // 关闭当前缓存
120
            return;
121
        }
122
123
        foreach ($except as $rule) {
124
            if (0 === stripos($request->url(), $rule)) {
125
                return;
126
            }
127
        }
128
129
        if (true === $key) {
130
            // 自动缓存功能
131
            $key = '__URL__';
132
        } elseif (strpos($key, '|')) {
133
            list($key, $fun) = explode('|', $key);
134
        }
135
136
        // 特殊规则替换
137
        if (false !== strpos($key, '__')) {
138
            $key = str_replace(['__CONTROLLER__', '__ACTION__', '__URL__'], [$request->controller(), $request->action(), md5($request->url(true))], $key);
139
        }
140
141
        if (false !== strpos($key, ':')) {
142
            $param = $request->param();
143
            foreach ($param as $item => $val) {
144
                if (is_string($val) && false !== strpos($key, ':' . $item)) {
145
                    $key = str_replace(':' . $item, $val, $key);
146
                }
147
            }
148
        } elseif (strpos($key, ']')) {
149
            if ('[' . $request->ext() . ']' == $key) {
150
                // 缓存某个后缀的请求
151
                $key = md5($request->url());
152
            } else {
153
                return;
154
            }
155
        }
156
157
        if (isset($fun)) {
158
            $key = $fun($key);
159
        }
160
161
        return [$key, $expire, $tag];
162
    }
163
}
164