PHP文件缓存实现

有些时候,我们不希望使用redis等第三方缓存,使得系统依赖于其他服务。这时候,文件缓存会是一个不错的选择。

我们需要文件缓存实现哪些功能:

功能实现:get、set、has、increment、decrement、delete、flush

能够在较短的时间内返回数据

支持key过期

    为了避免一个文件内的数据过大,造成读取文件的时候延迟较高,我们采用一个key-value一个文件的方式实现存储结构。

    为了支持key过期,我们需要把expire数据写入到文件中,所以需要对写入的数据进行序列化处理

    为了能够快速的定位到文件路径,我们采用hash算法一次计算出文件位置

<?php
class FileCache
{/*** 缓存目录* @var*/private $cache_dir;/*** @param $cache_dir* @throws Exception*/public function __construct($cache_dir){$this->cache_dir = $cache_dir;if (!is_dir($cache_dir)) {$make_dir_result = mkdir($cache_dir, 0755, true);if ($make_dir_result === false) throw new Exception('Cannot create the cache directory');}}/*** 根据key获取值,会判断是否过期* @param $key* @return mixed*/public function get($key){$cache_data = $this->getItem($key);if ($cache_data === false || !is_array($cache_data)) return false;return $cache_data['data'];}/*** 添加或覆盖一个key* @param $key* @param $value* @param $expire* @return mixed*/public function set($key, $value, $expire = 0){return $this->setItem($key, $value, time(), $expire);}/*** 设置包含元数据的信息* @param $key* @param $value* @param $time* @param $expire* @return bool*/private function setItem($key, $value, $time, $expire){$cache_file = $this->createCacheFile($key);if ($cache_file === false) return false;$cache_data = array('data' => $value, 'time' => $time, 'expire' => $expire);$cache_data = json_encode($cache_data);$put_result = file_put_contents($cache_file, $cache_data);if ($put_result === false) return false;return true;}/*** 创建缓存文件* @param $key* @return bool|string*/private function createCacheFile($key){$cache_file = $this->path($key);if (!file_exists($cache_file)) {$directory = dirname($cache_file);if (!is_dir($directory)) {$make_dir_result = mkdir($directory, 0755, true);if ($make_dir_result === false) return false;}$create_result = touch($cache_file);if ($create_result === false) return false;}return $cache_file;}/*** 判断Key是否存在* @param $key* @return mixed*/public function has($key){$value = $this->get($key);if ($value === false) return false;return true;}/*** 加法递增* @param $key* @param int $value* @return mixed*/public function increment($key, $value = 1){$item = $this->getItem($key);if ($item === false) {$set_result = $this->set($key, $value);if ($set_result === false) return false;return $value;}$check_expire = $this->checkExpire($item);if ($check_expire === false) return false;$item['data'] += $value;$result = $this->setItem($key, $item['data'], $item['time'], $item['expire']);if ($result === false) return false;return $item['data'];}/*** 减法递增* @param $key* @param int $value* @return mixed*/public function decrement($key, $value = 1){$item = $this->getItem($key);if ($item === false) {$value = 0 - $value;$set_result = $this->set($key, $value);if ($set_result === false) return false;return $value;}$check_expire = $this->checkExpire($item);if ($check_expire === false) return false;$item['data'] -= $value;$result = $this->setItem($key, $item['data'], $item['time'], $item['expire']);if ($result === false) return false;return $item['data'];}/*** 删除一个key,同事会删除缓存文件* @param $key* @return mixed*/public function delete($key){$cache_file = $this->path($key);if (file_exists($cache_file)) {$unlink_result = unlink($cache_file);if ($unlink_result === false) return false;}return true;}/*** 清楚所有缓存* @return mixed*/public function flush(){return $this->delTree($this->cache_dir);}/*** 递归删除目录* @param $dir* @return bool*/function delTree($dir){$files = array_diff(scandir($dir), array('.', '..'));foreach ($files as $file) {(is_dir("$dir/$file")) ? $this->delTree("$dir/$file") : unlink("$dir/$file");}return rmdir($dir);}/*** 根据key获取缓存文件路径** @param  string $key* @return string*/protected function path($key){$parts = array_slice(str_split($hash = md5($key), 2), 0, 2);return $this->cache_dir . '/' . implode('/', $parts) . '/' . $hash;}/*** 获取含有元数据的信息* @param $key* @return bool|mixed|string*/protected function getItem($key){$cache_file = $this->path($key);if (!file_exists($cache_file) || !is_readable($cache_file)) {return false;}$cache_data = file_get_contents($cache_file);if (empty($cache_data)) return false;$cache_data = json_decode($cache_data, true);if ($cache_data) {$check_expire = $this->checkExpire($cache_data);if ($check_expire === false) {$this->delete($key);return false;}}return $cache_data;}/*** 检查key是否过期* @param $cache_data* @return bool*/protected function checkExpire($cache_data){$time = time();$is_expire = intval($cache_data['expire']) !== 0 && (intval($cache_data['time']) + intval($cache_data['expire']) < $time);if ($is_expire) return false;return true;}
}

 

转载于:https://www.cnblogs.com/DoNetCShap/p/6230967.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/489286.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

影响计算机算法世界的十位大师(上)

来源&#xff1a;数学职业家1、伟大的智者——Don E.Knuth&#xff0c;中文名&#xff1a;高德纳(1938-)算法和程序设计技术的先驱者。Oh,God!一些国外网站这样评价他。一般说来&#xff0c;不知道此人的程序员是不可原谅的。其经典著作《计算机程序设计艺术》更是被誉为算法中…

echars显示折点数据_数据可视化的基础语法

数据可视化的基础语法可视化主要是以图像来展示数据间的关系&#xff0c;常见的图形种类有折线图,散点图,条形图&#xff0c;直方图&#xff0c;饼图。此外在接下来课程中还会用到箱线图&#xff0c;热力图&#xff0c;蜘蛛图&#xff0c;表示二元变量分布和成对关系的视图。今…

ajax 输入不为空,ajax POST响应为空

尝试通过单击按钮发布数据&#xff0c;但作为响应&#xff0c;PHP脚本中将其显示为空这是html这是jqueryvar action 1;$("input").on("click", sendData);function sendData() {if ( action 1 ) {$("#btn").css("background", "…

cad快捷键文件路径_办公格式转太难不会看这里!CAD、PDF、Word、Excel、TXT教你玩转...

办公格式转&#xff0c;你遇到最难解决的问题是哪些&#xff1f;办公格式转&#xff0c;最让你头疼的文件格式是哪些&#xff1f;办公格式转&#xff0c;你最想要学习转换格式有哪些&#xff1f;我&#xff1a;Word、Excel、PPT、TXT、CAD、PDF、JPG统统都想要进行解决&#xf…

80x86汇编—分支循环程序设计

文章目录 查表法: 实现16进制数转ASCII码显示计算AX的绝对值判断有无实根地址表形成多分支从100,99,...,2,1倒序累加输入一个字符&#xff0c;然后输出它的二进制数大小写转换大写转小写小写转大写 冒泡排序剔除空格 查表法: 实现16进制数转ASCII码显示 题目要求&#xff1a; …

jquery 获取键值对中最大值_jquery属性的操作

HTML示例代码&#xff1a;第一个标题家用电器分类家用电器价格11男&#xff1a;女:第一行第二行第三行第四行第二个标题第一段第二段属性&#xff1a;attr(n|k,v|p|f):设置或返回被选属性的值name:返回所有所选属性的值key,value:以键值对的方式设置所有所选属性的值properties…

python怎么一直循环_python 基础之while无限循环

用户登录程序 username "chenxi" passwed "testki" counter 0 while counter < 3: # 测试3次 user input("输入用户名&#xff1a;") passw input("输入密码&#xff1a;") if user username and passw passwed : print(&qu…

织梦服务器系统win10,WIN服务器爆破DEDECMS后台目录

利用脚本python&#xff1a;#!/usr/bin/env python/** author Mochazz* team 红日安全团队* env pyton3**/import requestsimport itertoolscharacters "abcdefghijklmnopqrstuvwxyz0123456789_!#"back_dir ""flag 0url "http://192.168.1.9/t…

人工智能技术对专利制度的挑战与应对

来源&#xff1a;上海市法学会内容摘要人工智能技术作为人类的一项发明创造&#xff0c;本身具备了一定的创造力。无论是专利法治实践还是理论研究均无法否认&#xff0c;在弱人工智能时代&#xff0c;人工智能技术兼具发明创造工具和发明创造方案的提供者的双重身份。由此导致…

java.lang.UnsupportedClassVersionError: Bad version number in .class file异常

java.lang.UnsupportedClassVersionError: Bad version number in .class file异常 部署工程时也出现过因为版本不同引起的问题&#xff0c;那时我们用的IDE的编译器是JDK5.0&#xff0c;而那台Linux装的是JDK6.0&#xff0c;部署后发现很多功能都出错&#xff0c;看来有些东西…

网络推广恶意点击js_做好网络推广,是做好网络营销的必要条件

互联网社会里网络无处不在&#xff0c;商机无处不在&#xff0c;企业通过网络营销&#xff0c;能有效的避免线下竞争激烈的市场&#xff0c;做好网络推广&#xff0c;是做好网络营销的必要条件。一个优秀的网络推广团队不但能实现提高企业的知名度的目的&#xff0c;还能帮助企…

css盒子模型_css的盒子模型是什么

CSS盒子模型就是在网页设计中经常用到的CSS技术所使用的一种思维模型。css盒子模型又称为框模型 (Box Model) &#xff0c;包含了元素内容(content)、内边距(padding)、边框(border)、外边距(margin)几个要素组成了盒子模型。图中最内部的框是元素的实际内容&#xff0c;也就是…

ajax实现重新绘图,如何画Flot AJAX更新图

在上一章我们提到了如何画实时更新图,而这一章就要教你们如何利用AJAX去后端抓数据回来做实时更新图.系统负载实时更新图(AJAX)我们直接拿上一章的范例来做修改,在这里只说明有修改到的部份,有任何不清楚的地方,你也可以随时回到上一章去查看.准备资料首先,因为我们画的是系统负…

6G应用场景有哪些?首份6G报告给你揭晓

来源&#xff1a; 5G产业圈导 读中国移动研究院无线与终端技术研究所所长丁海煜介绍称&#xff0c;按照移动通信产业“使用一代、建设一代、研发一代”的发展节奏&#xff0c;业界预期6G将于2030年左右实现商用。“创新、协调、绿色、开放、共享”应成为5G向6G演进的新发展理念…

linux python 图形界面开发_python在linux制作图形界面(snack)

snack是一个用于在linux制作图形界面&#xff08;GUI&#xff09;的模块&#xff0c;该模块由c编写&#xff0c;而且redhat的系统都自带这个模块。 1.获取模块 虽然redhat系统会自带这个模块&#xff0c;但是直接去import snack会提示找不到模块&#xff0c;一个原因是我们重装…

虚拟搭建局域网模拟器_巧用虚拟局域网,快速搭建私有云,一步就能搞定

前段时间公司一直在使用局域网来进行文件共享&#xff0c;用一台电脑把某个文件夹在局域网里共享出来&#xff0c;其他电脑远程访问&#xff0c;但是这样使用太麻烦&#xff0c;要是主电脑忘记开机&#xff0c;其它人就用不了。再就是&#xff0c;一旦离开公司之后&#xff0c;…

云服务器cvm只能弄网站么,云服务器cvm与建站主机区别

因此&#xff0c;云服务器cvm与建站主机的区别&#xff0c;其实也就是云服务器与虚拟主机之间的区别。安全可靠性云服务器cvm基于新型的虚拟主机现也位于云技术平台&#xff0c;安全稳定性较强。不过&#xff0c;由于CPU、带宽或IP等资源与其他空间共享&#xff0c;性能方面还是…

5个层级带你看清一颗芯片的内部结构

来源&#xff1a;北京物联网智能技术应用协会导 读在我们阐明半导体芯片之前&#xff0c;我们先应该了解两点。其一半导体是什么&#xff0c;其二芯片是什么。

python使用shell命令_python 调用shell命令的方法

在python程序中调用shell命令&#xff0c;是件很酷且常用的事情…… 1. os.system(command) 此函数会启动子进程&#xff0c;在子进程中执行command&#xff0c;并返回command命令执行完毕后的退出状态&#xff0c;如果command有执行内容&#xff0c;会在标准输出显示。这实际上…

ActiveRecord模式整理

DAO Data Access Object&#xff0c;数据访问对象 DAO是一个软件设计的指导原则&#xff0c;在核心J2EE模式中是这样介绍DAO模式的&#xff1a;为了建立一个健壮的J2EE应用&#xff0c;应该将所有对数据源的访问操作抽象封装在一个公共API中。用程序设计的语言来说&#xff0c;…