使用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中用foreach来操作数组的代码
Jul 17 PHP
php的array_multisort()使用方法介绍
May 16 PHP
PHP utf-8编码问题,utf8编码,数据库乱码,页面显示输出乱码
Apr 08 PHP
PHP数据类型的总结分析
Jun 13 PHP
Codeigniter操作数据库表的优化写法总结
Jun 12 PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
Jul 08 PHP
常见php数据文件缓存类汇总
Dec 05 PHP
smarty表格换行实例
Dec 15 PHP
PHP实现的一致性哈希算法完整实例
Nov 14 PHP
php微信开发之批量生成带参数的二维码
Jun 26 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
Mar 31 PHP
php实现通过stomp协议连接ActiveMQ操作示例
Feb 23 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中判断一个请求是ajax请求还是普通请求的方法
2011/06/28 PHP
详解PHP5.6.30与Apache2.4.x配置
2017/06/02 PHP
php精度计算的问题解析
2019/06/21 PHP
JavaScript中Array 对象相关的几个方法
2006/12/22 Javascript
javascript 兼容FF的onmouseenter和onmouseleave的代码
2008/07/19 Javascript
JavaScript实现Base64编码转换
2016/04/23 Javascript
JavaScript prototype属性详解
2016/10/25 Javascript
ajax接收后台数据在html页面显示
2017/02/19 Javascript
基于BootStrap的文本编辑器组件Summernote
2017/10/27 Javascript
详解vue的diff算法原理
2018/05/20 Javascript
vue生命周期实例小结
2018/08/15 Javascript
基于js Canvas实现二次贝塞尔曲线
2018/12/25 Javascript
vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法详解
2019/10/15 Javascript
微信小程序indexOf的替换方法(推荐)
2020/01/14 Javascript
解决Vue 给mapState中定义的属性赋值报错的问题
2020/06/22 Javascript
解决vue项目input输入框双向绑定数据不实时生效问题
2020/08/05 Javascript
[01:46]TI4西雅图DOTA2前线报道 中国选手抱团调时差
2014/07/08 DOTA
[01:32:10]NAVI vs VG Supermajor 败者组 BO3 第一场 6.5
2018/06/06 DOTA
详解Python网络爬虫功能的基本写法
2016/01/28 Python
浅谈python之新式类
2018/08/12 Python
Python matplotlib通过plt.scatter画空心圆标记出特定的点方法
2018/12/13 Python
selenium+python自动化测试环境搭建步骤
2019/06/03 Python
Python3中的最大整数和最大浮点数实例
2019/07/09 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
python opencv pytesseract 验证码识别的实现
2020/08/28 Python
html5的input的required使用中遇到的问题及解决方法
2018/04/24 HTML / CSS
英国最大的海报商店:GB Posters
2018/03/20 全球购物
伊莱克斯阿根廷网上商店:Tienda Electrolux
2021/03/08 全球购物
本科生的职业生涯规划范文
2014/01/09 职场文书
英语教育专业自荐信
2014/05/29 职场文书
大学生在校表现评语
2014/12/31 职场文书
成绩单家长意见
2015/06/03 职场文书
贷款收入证明范本
2015/06/12 职场文书
mysql升级到5.7时,wordpress导数据报错1067的问题
2021/05/27 MySQL
未发现nvidia显卡怎么办?Win11系统中未检测到nvidia显卡解决教程
2022/04/08 数码科技
古见同学有交流障碍症 第二季宣传CM公开播出
2022/04/11 日漫