Completed
Push — 6.0 ( d6c8d7...cb8a0b )
by liu
05:58
created

File::delete()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 8
ccs 0
cts 5
cp 0
crap 6
rs 10
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\cache\driver;
14
15
use think\cache\Driver;
16
17
/**
18
 * 文件缓存类
19
 */
20
class File extends Driver
21
{
22
    /**
23
     * 配置参数
24
     * @var array
25
     */
26
    protected $options = [
27
        'expire'        => 0,
28
        'cache_subdir'  => true,
29
        'prefix'        => '',
30
        'path'          => '',
31
        'hash_type'     => 'md5',
32
        'data_compress' => false,
33
        'tag_prefix'    => 'tag:',
34
        'serialize'     => [],
35
    ];
36
37
    /**
38
     * 有效期
39
     * @var int|\DateTime
40
     */
41
    protected $expire;
42
43
    /**
44
     * 架构函数
45
     * @param array $options 参数
46
     */
47
    public function __construct(array $options = [])
48
    {
49
        if (!empty($options)) {
50
            $this->options = array_merge($this->options, $options);
51
        }
52
53
        if (substr($this->options['path'], -1) != DIRECTORY_SEPARATOR) {
54
            $this->options['path'] .= DIRECTORY_SEPARATOR;
55
        }
56
    }
57
58
    /**
59
     * 取得变量的存储文件名
60
     * @access public
61
     * @param  string $name 缓存变量名
62
     * @return string
63
     */
64
    public function getCacheKey(string $name): string
65
    {
66
        $name = hash($this->options['hash_type'], $name);
67
68
        if ($this->options['cache_subdir']) {
69
            // 使用子目录
70
            $name = substr($name, 0, 2) . DIRECTORY_SEPARATOR . substr($name, 2);
71
        }
72
73
        if ($this->options['prefix']) {
74
            $name = $this->options['prefix'] . DIRECTORY_SEPARATOR . $name;
75
        }
76
77
        return $this->options['path'] . $name . '.php';
78
    }
79
80
    /**
81
     * 判断缓存是否存在
82
     * @access public
83
     * @param  string $name 缓存变量名
84
     * @return bool
85
     */
86
    public function has($name): bool
87
    {
88
        return false !== $this->get($name) ? true : false;
89
    }
90
91
    /**
92
     * 读取缓存
93
     * @access public
94
     * @param  string $name 缓存变量名
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 1 found
Loading history...
95
     * @param  mixed  $default 默认值
96
     * @return mixed
97
     */
98
    public function get($name, $default = false)
99
    {
100
        $this->readTimes++;
101
102
        $filename = $this->getCacheKey($name);
103
104
        if (!is_file($filename)) {
105
            return $default;
106
        }
107
108
        $content      = file_get_contents($filename);
109
        $this->expire = null;
110
111
        if (false !== $content) {
112
            $expire = (int) substr($content, 8, 12);
113
            if (0 != $expire && time() > filemtime($filename) + $expire) {
114
                //缓存过期删除缓存文件
115
                $this->unlink($filename);
116
                return $default;
117
            }
118
119
            $this->expire = $expire;
120
            $content      = substr($content, 32);
121
122
            if ($this->options['data_compress'] && function_exists('gzcompress')) {
123
                //启用数据压缩
124
                $content = gzuncompress($content);
125
            }
126
            return $this->unserialize($content);
127
        } else {
128
            return $default;
129
        }
130
    }
131
132
    /**
133
     * 写入缓存
134
     * @access public
135
     * @param  string        $name 缓存变量名
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
136
     * @param  mixed         $value  存储数据
137
     * @param  int|\DateTime $expire  有效时间 0为永久
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
138
     * @return bool
139
     */
140
    public function set($name, $value, $expire = null): bool
141
    {
142
        $this->writeTimes++;
143
144
        if (is_null($expire)) {
145
            $expire = $this->options['expire'];
146
        }
147
148
        $expire   = $this->getExpireTime($expire);
149
        $filename = $this->getCacheKey($name);
150
151
        $dir = dirname($filename);
152
153
        if (!is_dir($dir)) {
154
            try {
155
                mkdir($dir, 0755, true);
156
            } catch (\Exception $e) {
157
                // 创建失败
158
            }
159
        }
160
161
        $data = $this->serialize($value);
162
163
        if ($this->options['data_compress'] && function_exists('gzcompress')) {
164
            //数据压缩
165
            $data = gzcompress($data, 3);
166
        }
167
168
        $data   = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
169
        $result = file_put_contents($filename, $data);
170
171
        if ($result) {
172
            clearstatcache();
173
            return true;
174
        }
175
176
        return false;
177
    }
178
179
    /**
180
     * 自增缓存(针对数值缓存)
181
     * @access public
182
     * @param  string $name 缓存变量名
183
     * @param  int    $step 步长
184
     * @return false|int
185
     */
186
    public function inc(string $name, int $step = 1)
187
    {
188
        if ($this->has($name)) {
189
            $value  = $this->get($name) + $step;
190
            $expire = $this->expire;
191
        } else {
192
            $value  = $step;
193
            $expire = 0;
194
        }
195
196
        return $this->set($name, $value, $expire) ? $value : false;
197
    }
198
199
    /**
200
     * 自减缓存(针对数值缓存)
201
     * @access public
202
     * @param  string $name 缓存变量名
203
     * @param  int    $step 步长
204
     * @return false|int
205
     */
206
    public function dec(string $name, int $step = 1)
207
    {
208
        if ($this->has($name)) {
209
            $value  = $this->get($name) - $step;
210
            $expire = $this->expire;
211
        } else {
212
            $value  = -$step;
213
            $expire = 0;
214
        }
215
216
        return $this->set($name, $value, $expire) ? $value : false;
217
    }
218
219
    /**
220
     * 删除缓存
221
     * @access public
222
     * @param  string $name 缓存变量名
223
     * @return bool
224
     */
225
    public function delete($name): bool
226
    {
227
        $this->writeTimes++;
228
229
        try {
230
            return $this->unlink($this->getCacheKey($name));
231
        } catch (\Exception $e) {
232
            return false;
233
        }
234
    }
235
236
    /**
237
     * 清除缓存
238
     * @access public
239
     * @return bool
240
     */
241
    public function clear(): bool
242
    {
243
        $this->writeTimes++;
244
245
        $files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DIRECTORY_SEPARATOR : '') . '*');
246
247
        foreach ($files as $path) {
248
            if (is_dir($path)) {
249
                $matches = glob($path . DIRECTORY_SEPARATOR . '*.php');
250
                if (is_array($matches)) {
251
                    array_map('unlink', $matches);
252
                }
253
                rmdir($path);
254
            } else {
255
                unlink($path);
256
            }
257
        }
258
259
        return true;
260
    }
261
262
    /**
263
     * 删除缓存标签
264
     * @access public
265
     * @param  array $keys 缓存标识列表
266
     * @return void
267
     */
268
    public function clearTag(array $keys): void
269
    {
270
        foreach ($keys as $key) {
271
            $this->unlink($key);
272
        }
273
    }
274
275
    /**
276
     * 判断文件是否存在后,删除
277
     * @access private
278
     * @param  string $path
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
279
     * @return bool
280
     */
281
    private function unlink(string $path): bool
0 ignored issues
show
Coding Style introduced by
Private method name "File::unlink" must be prefixed with an underscore
Loading history...
282
    {
283
        return is_file($path) && unlink($path);
284
    }
285
286
}
287