3.2.2 - 普通 - 未处理
protected function _parseOptions($options=array())方法中有这么一行代码:// 查询过后清空sql表达式组装 避免影响下次查询
$this->options = array();但在下面紧接着的代码是用于判断是否有使用table连贯操作的:if(!isset($options['table'])){
// 自动获取表名
$options['table'] = $this->getTableName();
$fields = $this->fields;
}else{
// 指定数据表 则重新获取字段列表 但不支持类型检测
$fields = $this->getDbFields();
}如果通过table方法指定了与当前model不同的表名,则要用$this->getDbFields()来取得目标表的字段信息,getDbFields()方法中有如下代码:if(isset($this->options['table'])) {// 动态指定表名在这里又使用了$this->options,但这个$this->options已经在_parseOptions中被清空了。导致的问题:many to many关联的保存操作会把第三方关联表中的数据全删除掉。
如果在删除中使用了table,同时where条件中使用了table指定的表中的字段,此时会导致where被清空。造成问题的代码在delete方法中:
if(isset($options['where']) && is_array($options['where']) && !empty($fields) && !isset($options['join'])) {
// 对数组查询条件进行字段类型检查
foreach ($options['where'] as $key=>$val){
$key = trim($key);
if(in_array($key,$fields,true)){
if(is_scalar($val)) {
$this->_parseType($options['where'],$key);
}
}elseif(!is_numeric($key) && '_' != substr($key,0,1) && false === strpos($key,'.') && false === strpos($key,'(') && false === strpos($key,'|') && false === strpos($key,'&')){
unset($options['where'][$key]);
}
}
} 