Mybb1.8数据库核心操作update_query存在低级bug致数据丢失_PHP_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > PHP > Mybb1.8数据库核心操作update_query存在低级bug致数据丢失

Mybb1.8数据库核心操作update_query存在低级bug致数据丢失

 2014/10/22 17:30:10  cai21cn  程序员俱乐部  我要评论(0)
  • 摘要:Mybb1.6升级到1.8升级的过程中,遇到问题无数,近日发现了一个Mybb1.8数据库核心操作update_query的代码中存在严重bug,导致数据存入时漏掉前面的零,折腾数小时,发现错不在俺,而在mybb的升级代码。数据表:test字段IDint(10)AUTO_INCREMENTnamevarchar(60)notnullcategoryvarchar(5)在此表中category来表示分类,分类釆用常见的代码表示,共五位数字,前二位0l一99表示大类,后三位表示小类
  • 标签:数据库 数据 操作
Mybb1.6升级到1.8升级的过程中,遇到问题无数,近日发现了一个Mybb1.8数据库核心操作update_query的代码中存在严重bug,导致数据存入时漏掉前面的零,折腾数小时,发现错不在俺,而在mybb的升级代码。

数据表:test
字段
ID  int(10) AUTO_INCREMENT
name varchar(60) not null
category varchar(5)

在此表中category来表示分类,分类釆用常见的代码表示,共五位数字,前二位0l一99表示大类,后三位表示小类。在更新语句中通过Ajax提文更新,在台后语句中通过update_query更新数据。程序在1·6时工作正常,在开级1·8时更新混乱,检查下来发现category字段前面的“0”丢失。通过变化各种手段均不能解决问题。最后把Mybb的数据操作核心文件翻出来,对比其1.6版本发现代码存在低级bug,导致错误发生。

下面是1.8版数据更新过程
class="php">
	function update_query($table, $array, $where="", $limit="", $no_quote=false)
	{
		global $mybb;

		if(!is_array($array))
		{
			return false;
		}

		$comma = "";
		$query = "";
		$quote = "'";

		if($no_quote == true)
		{
			$quote = "";
		}

		foreach($array as $field => $value)
		{
			if(isset($mybb->binary_fields[$table][$field]) && $mybb->binary_fields[$table][$field])
			{
				if($value[0] != 'X') // Not escaped?
				{
					$value = $this->escape_binary($value);
				}
				
				$query .= $comma."`".$field."`={$value}";
			}
			else
			{
				if(is_numeric($value))
				{
					$query .= $comma."`".$field."`={$value}";
				}
				else
				{
					$query .= $comma."`".$field."`={$quote}{$value}{$quote}";
				}
			}
			$comma = ', ';
		}

		if(!empty($where))
		{
			$query .= " WHERE $where";
		}

		if(!empty($limit))
		{
			$query .= " LIMIT $limit";
		}

		return $this->write_query("
			UPDATE {$this->table_prefix}$table
			SET $query
		");
	}



而1.6版本是这样的
function update_query($table, $array, $where="", $limit="", $no_quote=false)
	{
		if(!is_array($array))
		{
			return false;
		}
		
		$comma = "";
		$query = "";
		$quote = "'";
		
		if($no_quote == true)
		{
			$quote = "";
		}
		
		foreach($array as $field => $value)
		{
			$query .= $comma."`".$field."`={$quote}{$value}{$quote}";
			$comma = ', ';
		}
		
		if(!empty($where))
		{
			$query .= " WHERE $where";
		}
		
		if(!empty($limit))
		{
			$query .= " LIMIT $limit";
		}

		return $this->write_query("
			UPDATE {$this->table_prefix}$table
			SET $query
		");
	}


发生错误的是这样几句

	if(is_numeric($value))
				{
					$query .= $comma."`".$field."`={$value}";
				}
				else
				{
					$query .= $comma."`".$field."`={$quote}{$value}{$quote}";
				}



传过来category的值可能是01002或08003,只要is_numeric($value)为真就是数字类型?!这是什么逻辑。其时mysql能自动处理识别字符型和数字型的差别,升级的1.8版把简单的事情复杂化,错误的逻辑导致bug发生,导致传过来的由数字组成的字符串存入数据库时前面的0丢失。如果前面不为0,就不会出错,这样导致数据一片混乱。

一直以来很欣赏Mybb简洁的代码和漂亮的系统架构,2M代码包括图片CSS等竟然能完成如此多的功能,给予用户良好的扩展能力。没想到翻出这样一个bug,见笑了。
上一篇: PHP 版本讲解 下一篇: php abc 配置详解
发表评论
用户名: 匿名