使用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调用三种数据库的方法(1)
Oct 09 PHP
php disk_free_space 返回目录可用空间
May 10 PHP
PHP Cookie的使用教程详解
Jun 03 PHP
php操作mysql数据库的基本类代码
Feb 25 PHP
PHP扩展开发入门教程
Feb 26 PHP
护卫神php套件 php版本升级方法(php5.5.24)
May 10 PHP
php生成过去100年下拉列表的方法
Jul 20 PHP
在Mac OS的PHP环境下安装配置MemCache的全过程解析
Feb 15 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
Jul 19 PHP
浅谈Yii乐观锁的使用及原理
Jul 25 PHP
php命名空间设计思想、用法与缺点分析
Jul 17 PHP
PHP预定义接口――Iterator用法示例
Jun 05 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
一个程序下载的管理程序(二)
2006/10/09 PHP
PHP-redis中文文档介绍
2013/02/07 PHP
PHP实现动态创建XML文档的方法
2018/03/30 PHP
PHP PDOStatement::bindParam讲解
2019/01/30 PHP
PHP _construct()函数讲解
2019/02/03 PHP
微信公众平台开发教程②微信端分享功能图文详解
2019/04/10 PHP
PHP http请求超时问题解决方案
2020/11/13 PHP
使Ext的Template可以解析二层的json数据的方法
2007/12/22 Javascript
在JavaScript中,为什么要尽可能使用局部变量?
2009/04/06 Javascript
浅析javascript中function 的 length 属性
2014/05/27 Javascript
javascript模拟实现ajax加载框实例
2014/10/15 Javascript
JavaScript获取当前网页标题(title)的方法
2015/04/03 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
Easyui的组合框的取值与赋值
2016/10/28 Javascript
vue.js,ajax渲染页面的实例
2018/02/11 Javascript
使用VueCli3+TypeScript+Vuex一步步构建todoList的方法
2019/07/25 Javascript
一行JavaScript代码如何实现瀑布流布局
2020/12/11 Javascript
[46:00]Ti4 冒泡赛第二轮LGD vs C9 2
2014/07/14 DOTA
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
python进阶教程之循环相关函数range、enumerate、zip
2014/08/30 Python
python循环监控远程端口的方法
2015/03/14 Python
python实现通过pil模块对图片格式进行转换的方法
2015/03/24 Python
python 实现屏幕录制示例
2019/12/23 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
Python通过TensorFLow进行线性模型训练原理与实现方法详解
2020/01/15 Python
将keras的h5模型转换为tensorflow的pb模型操作
2020/05/25 Python
Python SMTP配置参数并发送邮件
2020/06/16 Python
Python图像读写方法对比
2020/11/16 Python
python 操作excel表格的方法
2020/12/05 Python
全球游戏Keys和卡片市场:GamesDeal
2018/03/28 全球购物
Python面试题集
2012/03/08 面试题
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
新年联欢会主持词
2014/03/27 职场文书
家长会标语
2014/06/24 职场文书
银行工作心得体会范文
2016/01/23 职场文书
Ubuntu安装Mysql+启用远程连接的完整过程
2022/06/21 Servers