zoukankan      html  css  js  c++  java
  • 【教训】null == '',改造ThinkSNS 系统里面的一个缓存管理函数S()后,留下一个大bug

    本来想简化 ThinkSNS 系统里面的一个缓存管理函数:

    <?php
    /**
     * 用来对应用缓存信息的读、写、删除
     * $expire = null/0 表示永久缓存,否则为缓存有效期
     */
    function S($name, $value = '', $expire = null)
    {
    	static $_cache = array();   //减少缓存读取
    	$cache = model('Cache');
    	//$name = C('DATA_CACHE_PREFIX').$name;
    	
    	if ('' !== $value)
    	{
    		if (is_null($value))
    		{
    			// 删除缓存
    			$result = $cache->rm($name);
    			if ($result)
    			{
    				unset($_cache[$name]);
    			}
    
    			return $result;
    		}
    		else
    		{
    			// 缓存数据
    			$cache->set($name, $value, $expire);
    			$_cache[$name] = $value;
    		}
    
    		return true;
    	}
    	
    	if (isset($_cache[$name]))
    	{
    		return $_cache[$name];
    	}
    	
    	// 获取缓存数据
    	$value = $cache->get($name);
    	$_cache[$name] = $value;
    
    	return $value;
    }

    简化如下:

    /**
     * 内存缓存
     *
     * @param string $name 缓存键
     * @param string $value 缓存值(为''时,表示获取; 为null表示删除)
     * @param mixed $expire = null/0 表示永久缓存,否则为缓存有效期
     */
    function S($name, $value = '', $expire = null)
    {
    	$cache = model('Cache');
    
    	if ($value == '') // 获取缓存
    	{
    		return $cache->get($name);
    	}
    	elseif (is_null($value)) // 删除缓存
    	{
    		return $cache->rm($name);
    	}
    	else
    	{
    		return $cache->set($name, $value, $expire);
    	}
    }

    结果呢,留下了一个大bug,想通过 S('键名', null); 来删除某个缓存,死活不成功!

    通过跟踪,原来 当 $value = null 时,if ($value == '') 匹配成功,弱类型转换,即 null == '',所以需要把“等号”改为“恒等号”。即,把 if ($value == '') 改为 if ($value === ''),问题解决。

    /**
     * 内存缓存
     *
     * @param string $name 缓存键
     * @param string $value 缓存值(为''时,表示获取; 为null表示删除)
     * @param mixed $expire = null/0 表示永久缓存,否则为缓存有效期
     */
    function S($name, $value = '', $expire = null)
    {
    	$cache = model('Cache');
    
    	if ($value === '') // 获取缓存
    	{
    		return $cache->get($name);
    	}
    	elseif (is_null($value)) // 删除缓存
    	{
    		return $cache->rm($name);
    	}
    	else
    	{
    		return $cache->set($name, $value, $expire);
    	}
    }
    
  • 相关阅读:
    稳如车!半个世纪过去了,康威定律依然适用
    task.factory.startnew()
    RabbitMQ基础知识
    NLog类库使用探索——详解配置
    C# winform开发嵌套Chrome内核浏览器(WebKit.net)开发(一)
    C#客户端嵌入Chrome浏览器的实现
    TLS/HTTPS 证书生成与验证
    SSL证书/TLS证书是什么
    htmlparser
    动软代码生成器之模板功能介绍
  • 原文地址:https://www.cnblogs.com/52php/p/5675825.html
Copyright © 2011-2022 走看看