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;
}