使用PHP静态变量当缓存的方法


Posted in PHP onNovember 13, 2013

下面这个PHP的代码实例,功能是帮助用户重置密码,requestResetPassword是接收用户重置密码的请求并且做了相应的检查。为了更好的复用性,我将重置密码的操作单独分配到一个新的resetPassword的函数,更改完密码的后再调用sendEmail向用户发送一封通知邮件。

/**
 * 用户请求重置密码的接收器
 */
function requestResetPassword() {
    //检查用户是否存在
    if( !checkUserExists( $_GET['userid'] ) ) {
        exit('抱歉,用户不存在,请确认用户帐号。');
    }
    resetPassword( $_GET['userid'] );
    //最后向用户发送一封邮件
    sendEmail( $_GET['userid'], '重置密码成功', '新的密码是xxxx' );
    exit('新密码已经发送到你的邮箱。');
}/**
 * 帮助用户重置密码
 */
function resetPassword( $userid ) {
    //检查用户是否存在
    if( !checkUserExists( $userid ) ) {
        return false;
    }
    //进行重置用户密码的操作
    //略...
    return true;
}
/**
 * 向用户发送一封邮件
 */
function sendEmail( $userid, $title, $content ) {
    //检查用户是否存在
    if( !checkUserExists( $userid ) ) {
        return false;
    }
    //发送邮件操作
    //略...
    return true;
}
/**
 * 检查某个用户是否存在
 */
function checkUserExists( $userid ) {
    $user = getUserInfo( $userid );
    return !empty( $user );
}
/**
 * 获取某个用户的数据
 */
function getUserInfo( $userid ) {
    //假设我有一个query的函数,它用来查询数据库并返回数据
    $user = query( "SELECT * FROM `user` WHERE `uid`=" . intval( $userid ) );
    return is_array( $user ) ? $user : array() ;
}

现在问题是,这三个函数都同时使用checkUserExists这个函数来检查用户不存在,数据库查询了三次,这样带来了一些额外的开销。
如果要去掉三者之间任意一个checkUserExists,看上去是可能的。但是如果之后有某些功能要调用resetPassword或者sendEmail,用户不存在时,系统可能会发生错误。
还有一个解决方法是,将resetPassword的逻辑写到requestResetPassword里,再过一点,把sendEmail的逻辑也写进去。这样函数调用减少,数据库查询也变成一次了,性能得到了提高。但是重置密码和发送邮件的功能将不能得到复用,并且违背了单一责任的原则,代码复杂度也提高了。
不过,因为函数分离和复用性都很好,如果实际性能受到影响,可能考虑用缓存的方法减少数据库查询,我改动了它们共用的checkUserExists函数:
/**
 * 检查某个用户是否存在
 */
function checkUserExists( $userid ) {
    //增加一个缓存,用以记录检查用户的结果
    static $cache = array();    //检查当前用户是否已经检查过一次
    if( isset( $cache[ $userid ] ) ) {
        return $cache[ $userid ];
    }
    $user = getUserInfo( $userid );
    //把结果记录到缓存中
    $cache[ $userid ] = !empty( $user );
    return $cache[ $userid ];
}

也可以用同样的方法改动getUserInfo函数。
这里可以看到,当代码的复用性提高时,想提高性能是很简单的,性能的瓶颈也很容易被发现和修改。
尽管这个例子对性能影响还不够大,还有一些影响更大的,比如说遍历,我可能为了复用而将遍历封装到一个函数中,并且多次使用它。这些开销对我的项目根本没有预想中那样有太大的影响,或者说是微乎其微的。所以我更愿意把时间花在如何提高代码的复用性和维护性方面,而不是纠结于浪费多这一点性能。实际性能如果真的达不到要求,也可以权衡增加硬件配置。
PHP 相关文章推荐
php 动态多文件上传
Jan 18 PHP
PHP获取当前日期所在星期(月份)的开始日期与结束日期(实现代码)
Jun 18 PHP
PHP基于数组实现的分页函数实例
Aug 20 PHP
php采集内容中带有图片地址的远程图片并保存的方法
Jan 03 PHP
Laravel 5框架学习之Laravel入门和新建项目
Apr 07 PHP
thinkPHP中分页用法实例分析
Dec 26 PHP
PHP编程入门的基本语法知识点总结
Jan 26 PHP
Thinkphp框架中D方法与M方法的区别
Dec 23 PHP
php观察者模式应用场景实例详解
Feb 03 PHP
php获取目录下所有文件及目录(多种方法)(推荐)
May 14 PHP
php如何把表单内容提交到数据库
Jul 08 PHP
PHP读取文件或采集时解决中文乱码
Mar 09 PHP
使用phpQuery采集网页的方法
Nov 13 #PHP
phpQuery占用内存过多的处理方法
Nov 13 #PHP
PHP反射类ReflectionClass和ReflectionObject的使用方法
Nov 13 #PHP
php堆排序(heapsort)练习
Nov 13 #PHP
php生成EAN_13标准条形码实例
Nov 13 #PHP
使用php计算排列组合的方法
Nov 13 #PHP
测试php函数的方法
Nov 13 #PHP
You might like
PHP在字符断点处截断文字的实现代码
2011/04/21 PHP
PHP count_chars()函数讲解
2019/02/14 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
JS中彻底删除JSON对象组成的数组中的元素
2020/09/22 PHP
优化 JavaScript 代码的方法小结
2009/07/16 Javascript
jquery关于图形报表的运用实现代码
2011/01/06 Javascript
node.js中的fs.appendFileSync方法使用说明
2014/12/17 Javascript
js全选实现和判断是否有复选框选中的方法
2015/02/17 Javascript
jQuery.ajax实现根据不同的Content-Type做出不同的响应
2016/11/03 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
2017/01/18 Javascript
用JavaScript实现让浏览器停止载入页面的方法
2017/01/19 Javascript
bootstrap 通过加减按钮实现输入框组功能
2017/11/15 Javascript
如何更好的编写js async函数
2018/05/13 Javascript
解决vue-cli webpack打包后加载资源的路径问题
2018/09/25 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
vuex实现的简单购物车功能示例
2019/02/13 Javascript
VUE注册全局组件和局部组件过程解析
2019/10/10 Javascript
vue 获取url里参数的两种方法小结
2020/11/12 Javascript
python学习之第三方包安装方法(两种方法)
2015/07/30 Python
python安装oracle扩展及数据库连接方法
2017/02/21 Python
快速实现基于Python的微信聊天机器人示例代码
2017/03/03 Python
Python常见异常分类与处理方法
2017/06/04 Python
django manage.py扩展自定义命令方法
2018/05/27 Python
Python实现的企业粉丝抽奖功能示例
2019/07/26 Python
django 框架实现的用户注册、登录、退出功能示例
2019/11/28 Python
python开发入门——列表生成式
2020/09/03 Python
浅析rem和em和px vh vw和% 移动端长度单位
2016/04/28 HTML / CSS
What is the purpose of Void class? Void类的作用是什么?
2016/10/31 面试题
阿里巴巴Oracle DBA笔试题答案-备份恢复类
2013/11/20 面试题
办公室保洁员岗位职责
2013/12/02 职场文书
业务部经理岗位职责
2014/01/04 职场文书
测绘专业大学生职业生涯规划书
2014/02/10 职场文书
单位委托书范本(3篇)
2014/09/18 职场文书
2015年新教师工作总结
2015/04/28 职场文书
2015年高校教师个人工作总结
2015/05/25 职场文书
Win10鼠标轨迹怎么开 Win10显示鼠标轨迹方法
2022/04/06 数码科技