使用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 相关文章推荐
做一个有下拉功能的留言版
Oct 09 PHP
模仿OSO的论坛(二)
Oct 09 PHP
php开发工具之vs2005图解
Jan 12 PHP
PHP中的string类型使用说明
Jul 27 PHP
TMDPHP 模板引擎使用教程
Mar 13 PHP
php的memcache类分享(memcache队列)
Mar 26 PHP
Yii框架获取当前controlle和action对应id的方法
Dec 03 PHP
php获得网站访问统计信息类Compete API用法实例
Apr 02 PHP
php封装的图片(缩略图)处理类完整实例
Oct 19 PHP
详解PHP数据压缩、加解密(pack, unpack)
Dec 17 PHP
PHP implode()函数用法讲解
Mar 08 PHP
php设计模式之适配器模式原理、用法及注意事项详解
Sep 24 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 form 表单传参明细研究
2009/07/17 PHP
PHP 根据IP地址控制访问的代码
2010/04/22 PHP
php实现修改新闻时删除图片的方法
2015/05/12 PHP
PHP简单实现冒泡排序的方法
2016/12/26 PHP
PHP使用Nginx实现反向代理
2017/09/20 PHP
获取表单控件原始(初始)值的方法
2013/08/21 Javascript
jquery sortable的拖动方法示例详解
2014/01/16 Javascript
javascript实现捕捉键盘上按下的键
2015/05/05 Javascript
高性能JavaScript 重排与重绘(2)
2015/08/11 Javascript
深入浅析NodeJs并发异步的回调处理
2015/12/21 NodeJs
JavaScript判断数组重复内容的两种方法(推荐)
2016/06/06 Javascript
深入理解JavaScript函数参数(推荐)
2016/07/26 Javascript
JS中IP地址与整数相互转换的实现代码
2017/04/10 Javascript
基于Cookie常用操作以及属性介绍
2017/09/07 Javascript
JavaScript实现精美个性导航栏筋斗云效果
2017/10/29 Javascript
使用vue for时为什么要key【推荐】
2019/07/11 Javascript
微信小程序文字显示换行问题
2019/07/28 Javascript
原生javascript如何实现共享onload事件
2020/07/03 Javascript
[02:57]2014DOTA2国际邀请赛-观众采访
2014/07/19 DOTA
利用Python如何生成随机密码
2016/04/20 Python
对pandas的dataframe绘图并保存的实现方法
2017/08/05 Python
使用python 爬虫抓站的一些技巧总结
2018/01/10 Python
浅谈Python Opencv中gamma变换的使用详解
2018/04/02 Python
Python爬虫之正则表达式基本用法实例分析
2018/08/08 Python
Django框架下静态模板的继承操作示例
2019/11/08 Python
Python SQLAlchemy库的使用方法
2020/10/13 Python
Python 生成短8位唯一id实战教程
2021/01/13 Python
英国女士家居服网站:hush
2017/08/09 全球购物
新加坡最早生产电动滑板车的制造商之一:FunsToTheFore
2020/09/08 全球购物
自我鉴定怎么写
2014/01/12 职场文书
保护环境建议书400字
2014/05/13 职场文书
2015年纪念“卢沟桥事变”78周年活动方案
2015/05/06 职场文书
运动会主持人开幕词
2016/03/04 职场文书
面试提问mysql一张表到底能存多少数据
2022/03/13 MySQL
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang
Tomcat starup.bat 脚本实现开机自启动
2022/04/20 Servers