thinkphp有一个自动创建数据对象的create方法,核心代码如下
public function create($data='',$type='') { // 如果没有传值默认取POST数据 if(empty($data)) { $data = I('post.'); }elseif(is_object($data)){ $data = get_object_vars($data); } // 判断是否有主键,有代表修改,没有代表插入 $type = $type?:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT); // 生成数据对象,先获取该模型所有的字段$fields,过滤掉$data中不在field数据中的字段(最后剩下表中存在的字段) if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据 $fields = $this->getDbFields(); foreach ($data as $key=>$val){ if(!in_array($key,$fields)) { unset($data[$key]); }elseif(MAGIC_QUOTES_GPC && is_string($val)){ $data[$key] = stripslashes($val); } } } $this->data = $data; return $data; }
其中$this->getDbFields方法如下,该方法返回对应表字段名组成的索引数组
/** * 获取数据表字段信息 * @access public * @return array */ public function getDbFields(){ if(isset($this->options['table'])) {// 动态指定表名 $array = explode(' ',$this->options['table']); $fields = $this->db->getFields($array[0]); return $fields?array_keys($fields):false; } if($this->fields) { $fields = $this->fields; unset($fields['_type'],$fields['_pk']); return $fields; } return false; }
$this->db->getFields方法如下,该方法返回对应表的字段详细信息
public function getFields($tableName) { $result = $this->query('SHOW COLUMNS FROM '.$this->parseKey($tableName)); $info = array(); if($result) { foreach ($result as $key => $val) { $info[$val['Field']] = array( 'name' => $val['Field'], 'type' => $val['Type'], 'notnull' => (bool) (strtoupper($val['Null']) === 'NO'), // not null is empty, null is yes 'default' => $val['Default'], 'primary' => (strtolower($val['Key']) == 'pri'), 'autoinc' => (strtolower($val['Extra']) == 'auto_increment'), ); } } return $info; }