Heim > Artikel > Backend-Entwicklung > Der Mybb1.8-Datenbankkernvorgang „update_query“ weist geringfügige Fehler auf, die zu Datenverlust führen
Beim Upgrade von Mybb1.6 auf 1.8 sind wir auf unzählige Probleme gestoßen. Kürzlich haben wir einen schwerwiegenden Fehler im Code der Kernoperation update_query der Mybb1.8-Datenbank entdeckt, der dazu führte, dass die führenden Nullen fehlten Als die Daten gespeichert wurden, stellte ich nach ein paar Stunden fest, dass der Fehler nicht bei mir, sondern beim Upgrade-Code von mybb lag.
Datentabelle: test
field
ID int(10) AUTO_INCREMENT
name varchar ( 60) not null
category varchar(5)
In dieser Tabelle stellt die Kategorie die Klassifizierung dar, und die Klassifizierung wird durch allgemeine Codes insgesamt dargestellt von fünf Die ersten beiden Ziffern, 0l bis 99, repräsentieren Hauptkategorien und die letzten drei Ziffern repräsentieren kleine Kategorien. Aktualisieren Sie den Text über Ajax in der Update-Anweisung und die Daten über update_query in der Hintergrundanweisung. Das Programm funktionierte normal auf Level 1.6, aber das Update verlief chaotisch auf Level 1.8. Nach der Überprüfung stellte ich fest, dass die „0“ vor dem Kategoriefeld fehlte. Das Problem kann nicht durch den Wechsel verschiedener Mittel gelöst werden. Schließlich habe ich die Kerndatei für den Datenbetrieb von Mybb ausgegraben, sie mit Version 1.6 verglichen und festgestellt, dass der Code einen Fehler auf niedriger Ebene enthielt, der den Fehler verursachte.
下面是1.8版数据更新过程
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(!emptyempty($where)) { $query .= " WHERE $where"; } if(!emptyempty($limit)) { $query .= " LIMIT $limit"; } return $this->write_query(" UPDATE {$this->table_prefix}$table SET $query "); }
而1.6版本是这样的
Php代码
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(!emptyempty($where)) { $query .= " WHERE $where"; } if(!emptyempty($limit)) { $query .= " LIMIT $limit"; } return $this->write_query(" UPDATE {$this->table_prefix}$table SET $query "); }
发生错误的是这样几句
Php代码
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,见笑了。1.6至1.8改动很大,发布过于仓促。总体说来,Mybb不失一个漂亮简洁的php论坛。