/**
* 创建数据对象 但不保存到数据库
* @access public
* @param mixed $data 创建数据
* @param string $type 状态
* @return mixed
*/
public function create($data='',$type='') {
// 如果没有传值默认取POST数据
if(empty($data)) {
$data = I('post.');
}elseif(is_object($data)){
$data = get_object_vars($data);
}
// 验证数据
if(empty($data) || !is_array($data)) {
$this->error = L('_DATA_TYPE_INVALID_');
return false;
}
// 状态
$type = $type?:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT);
// 检查字段映射
if(!empty($this->_map)) {
foreach ($this->_map as $key=>$val){
if(isset($data[$key])) {
$data[$val] = $data[$key];
unset($data[$key]);
}
}
}
// 检测提交字段的合法性
if(isset($this->options['field'])) { // $this->field('field1,field2...')->create()
$fields = $this->options['field'];
unset($this->options['field']);
}elseif($type == self::MODEL_INSERT && isset($this->insertFields)) {
$fields = $this->insertFields;
}elseif($type == self::MODEL_UPDATE && isset($this->updateFields)) {
$fields = $this->updateFields;
}
if(isset($fields)) {
if(is_string($fields)) {
$fields = explode(',',$fields);
}
// 判断令牌验证字段
if(C('TOKEN_ON')) $fields[] = C('TOKEN_NAME');
foreach ($data as $key=>$val){
if(!in_array($key,$fields)) {
unset($data[$key]);
}
}
}
// 数据自动验证
if(!$this->autoValidation($data,$type)) return false;
// 表单令牌验证
if(!$this->autoCheckToken($data)) {
$this->error = L('_TOKEN_ERROR_');
return false;
}
// 验证完成生成数据对象
$fields = $this->getDbFields();
if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据
$diff = array_diff(array_keys($data),$fields);
foreach ($diff as $key){
unset($data[$key]);
}
}
$intersect = array_intersect($fields,array_keys($data));
foreach ($intersect as $key) {
if(MAGIC_QUOTES_GPC && is_string($data[$key])){
$data[$key] = stripslashes($data[$key]);
}
}
// 创建完成对数据进行自动处理
$this->autoOperation($data,$type);
$this->_after_create($data,$this->options); //回调
// 赋值当前数据对象
$this->data = $data;
// 返回创建的数据以供其他调用
return $data;
}
// 创建数据对象后的回调方法
protected function _after_create(&$data,$options) {}改动地方为: // 验证完成生成数据对象
$fields = $this->getDbFields();
if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据
$diff = array_diff(array_keys($data),$fields);
foreach ($diff as $key){
unset($data[$key]);
}
}
$intersect = array_intersect($fields,array_keys($data));
foreach ($intersect as $key) {
if(MAGIC_QUOTES_GPC && is_string($data[$key])){
$data[$key] = stripslashes($data[$key]);
}
}新增了回调函数 // 创建数据对象后的回调方法
protected function _after_create(&$data,$options) {}在create方法的最后执行$this->_after_create($data,$this->options);进行回调 // 表单验证成功后的回调方法
protected function _after_create(&$data,$options) {
// 获取关联数据 并附加到结果中
if(!empty($options['link']))
$this->crRelation($data,$options['link']);
} /**
* 关联数据验证
* @access protected
* @param mixed $data 数据对象
* @param string $name 关联名称
* @return mixed
*/
protected function crRelation(&$data='',$name='') {
if(empty($data) && !empty($this->data)){
$data = $this->data;
}elseif(!is_array($data)){
// 数据无效返回
return false;
}
if(!empty($this->_link)) {
$fields = $this->getDbFields();
// 遍历关联定义
foreach($this->_link as $key=>$val) {
// 操作制定关联类型
$mappingName = $val['mapping_name']?$val['mapping_name']:$key; // 映射名称
if(empty($name) || true === $name || $mappingName == $name || (is_array($name) && in_array($mappingName,$name)) ) {
// 操作制定的关联
$mappingType = !empty($val['mapping_type'])?$val['mapping_type']:$val; // 关联类型
$mappingClass = !empty($val['class_name'])?$val['class_name']:$key; // 关联类名
$mappingKey =!empty($val['mapping_key'])? $val['mapping_key'] : $this->getPk(); // 关联键名
if(strtoupper($mappingClass)==strtoupper($this->name)) {
continue; // 自引用关联跳过
}
// 获取关联model对象
$model = D($mappingClass);
foreach ($model->getDbFields() as $field) {
if (array_key_exists($field, $data) && $field != $mappingKey) {
$_data[$field] = $data[$field];
unset($data[$field]);
}
}
if ($_data = $model->token(false)->create($_data)) {
$data[$mappingName] = $_data;
$fields[] = $mappingName;
} else {
$this->error = $model->getError();
return false;
}
}
}
// 过滤非法字段数据
$diff = array_diff(array_keys($data),$fields);
foreach ($diff as $key){
unset($data[$key]);
}
}
}改动了relation方法,增加了一句$this->autoCheckFields = false; /**
* 进行关联查询
* @access public
* @param mixed $name 关联名称
* @return Model
*/
public function relation($name) {
$this->options['link'] = $name;
$this->autoCheckFields = false; //执行create方法时不过滤字段
return $this;
} 附件 Relation.rar ( 15.81 KB 下载:52 次 )
ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。