Passed
Push — master ( 729fd7...f34cda )
by 世昌
01:58
created

FileCache::set()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 3
nop 3
dl 0
loc 13
rs 9.9666
c 0
b 0
f 0
1
<?php
2
namespace nebula\application\cache;
3
4
use nebula\application\filesystem\FileSystem;
5
use nebula\component\cacheable\CacheInterface;
6
7
/**
8
 * 文件缓存
9
 *
10
 * 由于访问数据库的效率远远低于访问文件的效率,所以我添加了一个文件缓存类,
11
 * 你可以把常用的数据和更改很少的数据查询数据库以后缓存到文件里面,用来加快页面加载速度。
12
 */
13
class FileCache implements CacheInterface
14
{
15
    protected $path;
16
    protected $value;
17
    protected $defaultLiveTime = 3600;
18
19
    public function __construct(string $path, int $live = 3600)
20
    {
21
        $this->path = $path;
22
        $this->defaultLiveTime = $live;
23
        FileSystem::makes($path);
24
    }
25
26
27
    /**
28
     * 设置
29
     * @param string $name 名
30
     * @param mixed $value 值
31
     * @param int $expire 过期时间
32
     * @return bool
33
     */
34
    public function set(string $name, $value, int $expire=null):bool
35
    {
36
        if ($this->disable()) {
37
            return false;
38
        }
39
        $path=$this->getPath($name);
40
        $this->value[$name]=$value;
41
        FileSystem::makes(dirname($path));
42
        $value=serialize($value);
43
        if (is_null($expire)) {
44
            $expire=time() + $this->defaultLiveTime;
45
        }
46
        return file_put_contents($path, $expire.'|'.$value)!==false;
47
    }
48
49
    /**
50
     * 获取值
51
     * @param string $name 名
52
     * @return mixed|null
53
     */
54
    public function get(string $name, $defalut=null)
55
    {
56
        // 有值就获取值
57
        if (array_key_exists($name, $this->value)) {
58
            $value=$this->value[$name];
59
            return $value;
60
        }
61
        // 没值就在cache文件中查找
62
        $path=$this->getPath($name);
63
        if (FileSystem::exist($path)) {
64
            $value=FileSystem::get($path);
65
            list($time, $value)=explode('|', $value, 2);
66
            if (time()<intval($time)) {
67
                // 未过期则返回
68
                return unserialize($value);
69
            } else {
70
                // 过期则删除
71
                $this->delete($path);
72
            }
73
        }
74
        // 返回默认值
75
        return $defalut;
76
    }
77
78
    /**
79
     * 删除值
80
     * @param string $name 名
81
     * @return bool
82
     */
83
    public function delete(string $name) :bool
84
    {
85
        return FileSystem::delete($this->getPath($name));
86
    }
87
    
88
    
89
    /**
90
     * 检测是否存在
91
     *
92
     * @param string $name
93
     * @return bool
94
     */
95
    public function has(string $name):bool
96
    {
97
        return $this->get($name)!==null;
98
    }
99
100
    /**
101
     * 垃圾回收
102
     */
103
    public function gc()
104
    {
105
        $files=FileSystem::readFiles($this->path, true);
106
        foreach ($files as $file) {
107
            $value=FileSystem::get($file);
108
            list($time, $value)=explode('|', $value, 2);
109
            if (time()>intval($time)) {
110
                FileSystem::delete($file);
111
            }
112
        }
113
    }
114
115
    public function clear()
116
    {
117
        FileSystem::delete($this->path);
118
    }
119
120
    public function enable():bool
121
    {
122
        return is_writable($this->path);
123
    }
124
125
    public function disable():bool
126
    {
127
        return !$this->enable();
128
    }
129
130
    private function getPath(string $name)
131
    {
132
        if (strpos($name, '.')) {
133
            list($main, $sub)=explode('.', $name, 2);
134
        } else {
135
            $main=$name;
136
            $sub=$name;
137
        }
138
        $fname= $this->path.'/'.substr(md5($main), 0, 8).'-'.substr(md5($sub), 0, 4).'.cache';
139
        return $fname;
140
    }
141
}
142