接着上一篇的讲,从数据库中取出数据后,需要对其进行缓存,减少数据库服务器连接压力。此处用到的是文件缓存形式,首先谈谈我了解到的三种缓存:文件缓存、memcache缓存、redis缓存;
1、文件缓存:将数据库数据取出后,存放在文件中,读取文件其实也是读写磁盘,与MySQL无异,不过它减少了连接数据库的时间,从文件中直接读取数据要比从数据库中读取数据快。
2、memcache缓存:它是一个缓存系统,需要用到扩展;其实它的连接就向连接数据库那样,只不过它的数据是存储在内存之中,因此它的读取速度是非常快的,尽管它也需要产生一个连接时间!
3、redis缓存:redis是数据库系统,有点像memcache+mongoDb的结合体;它的连接方式也跟memcache类似,具体的我也不太了解了。
本篇文章使用文件缓存,不需要安装什么扩展,之后有机会再写一个memcache缓存的类。
最主要的就是cacheData()函数,以及其中的参数:这里大致说一下,当value为空时,就是获取缓存;当value有值传入时,就是缓存数据;一定要明白这一点!接下来上整个代码:
_dir = dirname(__FILE__).'/files/';
}
/*
*数据缓存
*@param string $key 文件名
*@param array $value 数据
*@param int $cacheTime 缓存失效时间
*return file or string
*/
public function cacheData($key,$value = '',$cacheTime = 0){
$filename = $this->_dir.$key.self::EXT;
//将value值写入缓存
if($value !== ''){
//值为null时,删除文件
if(is_null($value)){
return @unlink($filename);
}
$dir = dirname($filename);
if(!is_dir($dir)){
mkdir($dir,0777);
}
$cacheTime = sprintf('%011d',$cacheTime);
return file_put_contents($filename,$cacheTime.json_encode($value));
}
//获取缓存
if(!is_file($filename)){
return false;
}else{
$content = file_get_contents($filename);
$cacheTime = (int)substr($content,0,11);
$value = substr($content,11);
//缓存失效删除
if($cacheTime !=0 && $cacheTime+filemtime($filename) < time()){
unlink($filename);
return false;
}
return json_decode($value,true);
}
}
}
第一点:构造函数中生成了一个文件路径,用来存放缓存数据。dirname():返回去掉文件名后的目录名,F:\wamp\www\api;而全局常量__File__:返回本文件的路径:F:\wamp\www\api\test.php;
第二点:注意点:代码中的$filename = $this->_dir.$key.self::EXT;是一个文件路径;$dir = dirname($filename);是一个目录路径;所以对它们所做的判断也是不同的!!!第一个是is_file();第二个是is_dir();
第三点:return @unlink($filename);@表示不报错,不希望前端看到这个错误;这个符号尽量少用!
第四点:如果此目录不存在,就创建目录,并授予所有用户都可以读写执行的权限,0777其中的0表示的是SUID、SGID以及粘着位(sticky bit)权限(这个权限挺重要的!),这里不细谈了;777表示属主、属组、other的权限设置,此处为都可以读写执行;
$dir = dirname($filename);
if(!is_dir($dir)){
mkdir($dir,0777);
}
第五点:$cacheTime = sprintf('%011d',$cacheTime);因为缓存时间的长度不确定,所以可以用sprintf将长度转化为一样,比如,$cacheTime = 120时,sprintf('%011d',$cacheTime)就是00000000120;方便后面截取!
第六点:file_put_contents($filename,$cacheTime.json_encode($value));将值存入文件并返回;生成一个文件;
第七点:这段代码挺严格的,接触到不少新的函数,(int)的用法;filemtime()获取文件缓存时间,即下面的判断是:用户设置了缓存时间($cacheTime != 0),以及缓存失效时间+文件缓存时间小于当前时间时,删除文件($cacheTime+filemtime($filename) < time()),然后返回false,这个返回值一定注意需要写上!如果不写该返回值,此cacheTime()在value值为空情况下,就可能无返回值,这是很不好的代码!写上的话,便于别人阅读,知道到了这就不会执行下面的代码了!
if(!is_file($filename)){
return false;
}else{
$content = file_get_contents($filename);
$cacheTime = (int)substr($content,0,11);
$value = substr($content,11);
//缓存失效删除
if($cacheTime !=0 && $cacheTime+filemtime($filename) < time()){
unlink($filename);
return false;
}
return json_decode($value,true);
}