/
FileCache.class.php
executable file
·220 lines (203 loc) · 6.21 KB
/
FileCache.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
<?php
/*
* @link http://kodcloud.com/
* @author warlee | e-mail:kodcloud@qq.com
* @copyright warlee 2014.(Shanghai)Co.,Ltd
* @license http://kodcloud.com/tools/license/license.txt
*/
/**
* 数据的缓存存储类;key=>value 模式;value可以是任意类型数据。
* 完整流程测试;读取最低5000次/s 含有写的1000次/s
* get($find=null)
* 1.get(); //返回所有
* 2.get(key); //直接通过key获取
* 3.get(data_key,value); //搜索key为value的数据 直接返回数据不含key
* 4.get(array('key','value')); //搜索数据,符合key为指定value的所有数据;key value形式
*
* set($find=null,$change=null)
* 1.set(string,val) //添加或更新;
* 2.set(array('key','value_find'),array('key','change_to')) //查找方式更新 多条数据
*
* remove($find,$value)
* 1.remove(); //清空
* 2.remove(string); //删除 eg:set('37'),删除key为37的数据 存在且删除成功则返回true
* 3.remove(array('key','value_find')); //查找方式删除;多条数据
* reset($arr);//初始化数据
*/
define('CONFIG_EXIT', '<?php exit;?>');
class FileCache{
private $data;
private $file;
private $fileHash;//最后一次修改;保存时判断,如果有新修改则先读取再保存
function __construct($file) {
$this->file = $file;
$this->data= self::load($file);
$this->fileChangeCheck();
}
public function get($find=null,$value=null){
if (is_null($find)){
return $this->data;
}else if(is_array($find)){//查找内容数据方式获取;返回多条
$result = array();
foreach ($this->data as $key => $val) {
if ($val[$find[0]] == $find[1]) {
$result[$key] = $this->data[$key];
}
}
if(count($result)!=0){
return $result;
}
}else{//单条数据获取
$find .= '';//字符串
if(!is_null($value)){//通过某个key寻找单条数据
foreach ($this->data as $key => $val) {
if ($val[$find] == $value) {
return $val;
}
}
}
if(isset($this->data[$find])){
return $this->data[$find];
}
}
return false;
}
//添加或更新
public function set($find,$value){
$this->fileChangeCheck();
//最后有修改则先更新本地。
if(is_string($find)){//单条数据更新
$this->data[$find] = $value;
}else if(is_array($find)){//查找方式更新;更新多条
foreach ($this->data as $key => $val) {
if ($val[$find[0]] == $find[1]) {
$this->data[$key][$value[0]] = $value[1];
}
}
}else{
return false;
}
self::save($this->file,$this->data);
return true;
}
//删除,查找删除
public function remove($find){
$this->fileChangeCheck();
if(is_string($find)){//单条数据删除
unset($this->data[$find]);
}else if(is_array($find)){//查找删除
foreach ($this->data as $key => $val) {
if ($val[$find[0]] == $find[1]){
unset($this->data[$key]);
}
}
}else{
return false;
}
self::save($this->file,$this->data);
return true;
}
private function fileChangeCheck(){
if(is_null($this->fileHash)){
$this->fileHash = @md5_file($this->file);
return;
}
//是否发生改变
$lastHash = @md5_file($this->file);
if($lastHash != $this->fileHash){
$this->fileHash = $lastHash;
$this->data= self::load($this->file);
}
}
public function reset($data,$save = true){
$this->data = $data;
if($save){
self::save($this->file,$this->data);
}
}
//=====================================================
public static function arrSort(&$arr,$key, $type = 'asc'){
$keysValue = $newArray = array();
foreach ($arr as $k => $v) {
$keysValue[$k] = $v[$key];
}
if ($type == 'asc') {
asort($keysValue);
} else {
arsort($keysValue);
}
reset($keysValue);
foreach ($keysValue as $k => $v) {
$newArray[$k] = $arr[$k];
}
return $newArray;
}
public function getMaxId(){
$minId = 100;
if(count($this->data)==0){
return $minId;//一切从100开始
}
$idArr = array_keys($this->data);
rsort($idArr,SORT_NUMERIC);//id从高到底
$the_id = intval($idArr[0])+1;
if($the_id<=$minId){
return $minId;
}
return $the_id;
}
/**
* 加载数据;并解析成程序数据
*/
public static function load($file){//10000次需要4s 数据量差异不大。
if (!$file) return false;
$file = iconv_system($file);
if ( !file_exists($file) ){
@file_put_contents($file,CONFIG_EXIT.'[]');
chmod_path($file,0777);
return array();
}
$str = file_read_safe($file,10.5);
if( $str === false || $str === 0 || $str === -1){
show_tips('[Error Code:1010] FileCache data read error!<br/>'.get_path_this($file));
}
if (strlen($str) == 0 ||
strlen($str) == strlen(CONFIG_EXIT) ){
@file_put_contents($file,CONFIG_EXIT.'[]');
chmod_path($file,0777);
return array();
}
if($str === false || strlen($str) < strlen(CONFIG_EXIT) ){
show_tips('[Error Code:1011] FileCache data error!<br/>'.get_path_this($file));
}
$data= json_decode(substr($str, strlen(CONFIG_EXIT)),true);
if (is_null($data)) $data = array();
return $data;
}
/**
* 保存数据;
*/
public static function save($file,$data){//10000次需要6s
if (!$file) return false;
$file = iconv_system($file);
if ( !file_exists($file) ){
@file_put_contents($file,CONFIG_EXIT.'[]');
chmod_path($file,0777);
}
if (!path_writeable($file)) {
show_tips(BASIC_PATH."<br/>".LNG('path_can_not_write_data'));
}
if(defined('JSON_PRETTY_PRINT')){
$jsonStr = json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
}else{
$jsonStr = json_encode($data);
}
if(is_null($jsonStr) || strlen($jsonStr) == 0){//含有二进制或非utf8字符串对应检测
show_tips('[Error Code:1013] json_encode error!<br/>'.get_path_this($file));
}
$result = file_wirte_safe($file,CONFIG_EXIT.$jsonStr,10.5);
if($result === false){
show_tips('[Error Code:1012] FileCache save error!<br/>'.get_path_this($file));
}
return $result;
}
}