Thinkphp3.2.3 解决关联模型的自动生成问题($_auto)
来源:互联网 发布:辐射4阴影优化补丁 编辑:程序博客网 时间:2024/06/05 20:57
在Thinkphp中,关联模型经常会被使用到,然而最近在使用的时候发现关联模型中的自动生成功能有些问题。
例如有一个类IdeaDetailModel对应表oidea_idea_detail,它有一个简表oidea_idea_simple(类IdeaSimpleModel),IdeaDetailModel代码如下(只保留了部分功能):
<?phpnamespace Idea\Model;use Think\Model\RelationModel;class IdeaDetailModel extends RelationModel{ protected $tableName = 'idea_detail'; /* 关系模型 */ protected $_link = array( // 与IdeaSimple关联(一对一:HAS_ONE) 'Simple' => array( 'mapping_type' => self::HAS_ONE, 'class_name' => 'IdeaSimple', 'mapping_name' => 'Simple', 'foreign_key' => 'iid', 'relation_foreign_key' => 'id', 'mapping_fields' => 'star,heart,watch', ), ); /* Idea模型自动完成 */ protected $_auto = array( array('read', 0, self::MODEL_INSERT), array('comment', 0, self::MODEL_INSERT), array('status', 1, self::MODEL_INSERT), array('create_time', NOW_TIME, self::MODEL_INSERT), array('update_time', NOW_TIME, self::MODEL_BOTH), ); public function addIdea($uid, $arrIdeaInfo = null) { /*做些验证*/ //写入数据库 $data = array('src_uid' => $uid, 'title' => $arrIdeaInfo['title'], 'summary' => $arrIdeaInfo['summary']); $data['Simple'] = $data; $data['content'] = $arrIdeaInfo['content']; $data = $this->create($data); if (!$data) { return false; } $res = $this->relation(array('Simple'))->add($data); return $res; } }
IdeaSimpleModel类代码如下(只保留部分功能):
<?phpnamespace Idea\Model;use Think\Model\RelationModel;/****/class IdeaSimpleModel extends RelationModel{ /* Idea模型自动完成 */ protected $_auto = array( array('star', 0, self::MODEL_INSERT), array('heart', 0, self::MODEL_INSERT), array('watch', 0, self::MODEL_INSERT), array('status', 1, self::MODEL_INSERT), array('update_time', NOW_TIME, self::MODEL_BOTH), );}
如果我们调用IdeaDetailModel类的addIdea方法,实际上是不能实现IdeaSimpleModel中的自动完成功能的。
解决方法如下(参考了http://www.thinkphp.cn/code/833.html,实际上是对Think\RelationModel类的部分函数进行了覆盖,而我在其中添加了函数createRelationData):
<?phpnamespace Common\Model;use Think\Model\RelationModel;/** * 关联模型自动完成类,重载RelationModel中的create方法 * 在使用关联模型并且需要自动完成的时候使用该类 */class AutoCompleteRelationModel extends RelationModel{ /** * 重载create方法,不过滤字段,并且生成需要数据 */ function create($data = '', $type = '') { // 如果没有传值默认取POST数据 if (empty($data)) { $data = $_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 ? $type : (!empty($data[$this->getPk() ]) ? self::MODEL_UPDATE : self::MODEL_INSERT); // 数据自动验证 if (!$this->autoValidation($data, $type)) return false; // 表单令牌验证 if (!$this->autoCheckToken($data)) { $this->error = L('_TOKEN_ERROR_'); return false; } // 验证完成生成数据对象 if ($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据 $fields = $this->getDbFields(); foreach ($data as $key => $val) { if (MAGIC_QUOTES_GPC && is_string($val)) { $data[$key] = stripslashes($val); } } } // 创建完成对数据进行自动处理 $data=$this->autoOperation($data, $type); $data = $this->createRelationData($data); // $data=$this->createData($data); // 返回创建的数据以供其他调用 return $data; } /** * 自动表单处理 * @access public * @param array $data 创建数据 * @param string $type 创建类型 * @return mixed */ private function autoOperation($data, $type) { if (!empty($this->options['auto'])) { $_auto = $this->options['auto']; unset($this->options['auto']); } elseif (!empty($this->_auto)) { $_auto = $this->_auto; } // 自动填充 if (isset($_auto)) { foreach ($_auto as $auto) { // 填充因子定义格式 // array('field','填充内容','填充条件','附加规则',[额外参数]) if (empty($auto[2])) $auto[2] = self::MODEL_INSERT; // 默认为新增的时候自动填充 if ($type == $auto[2] || $auto[2] == self::MODEL_BOTH) { switch (trim($auto[3])) { case 'function': // 使用函数进行填充 字段的值作为参数 case 'callback': // 使用回调方法 $args = isset($auto[4]) ? (array)$auto[4] : array(); if (isset($data[$auto[0]])) { array_unshift($args, $data[$auto[0]]); } if ('function' == $auto[3]) { $data[$auto[0]] = call_user_func_array($auto[1], $args); } else { $data[$auto[0]] = call_user_func_array(array(&$this, $auto[1] ) , $args); } break; case 'field': // 用其它字段的值进行填充 $data[$auto[0]] = $data[$auto[1]]; break; case 'ignore': // 为空忽略 if ('' === $data[$auto[0]]) unset($data[$auto[0]]); break; case 'string': default: // 默认作为字符串填充 $data[$auto[0]] = $auto[1]; } if (false === $data[$auto[0]]) unset($data[$auto[0]]); } } } return $data; } /** * 生成关联模型需要的数据 */ function createData($data) { foreach ($data as $k => $v) { if (in_array($k, $this->fields)) { $data['Detail'][$k] = $v; unset($data[$k]); } } //删除多余字段 unset($data['nid']); unset($data['create_date']); return $data; } /** * ADD * 对关联模型使用D函数,从而实现自动完成 */ function createRelationData($data) { $linkKeys = array_keys($this->_link); if (empty($linkKeys) || !is_array($linkKeys)) { return $data; } $arrMappingName = array(); foreach ($linkKeys as $index => $key) { if (isset($this->_link[$key]['mapping_name'])) { array_push($arrMappingName, $this->_link[$key]['mapping_name']); unset($linkKeys[$index]); } } $arrMappingName = array_merge($arrMappingName, $linkKeys); foreach ($data as $model => $item) { if (in_array($model, $arrMappingName)) { $tempData = D($this->_link[$model]['class_name'])->create($item); $data[$model] = $tempData; } } return $data; }}
这样就可以让关联模型支持自动完成功能了。使用方法:
<?phpnamespace Idea\Model;use Common\Model\AutoCompleteRelationModel;// use Think\Model\RelationModel;/*** Idea model* 对应表oidea_idea*/class IdeaDetailModel extends AutoCompleteRelationModel{ /*同上,不变*/}
水平有限,欢迎指正~
0 0
- Thinkphp3.2.3 解决关联模型的自动生成问题($_auto)
- ThinkPHP3.2的关联模型
- Thinkphp3.2.3关联模型(总结)
- thinkphp模型$_auto自动完成设置为插入时更新操作也变化的解决办法
- thinkphp3.2.3-关联模型(多对多)
- 完美解决thinkphp3的mysql连接问题
- ThinkPHP3.2.3生成二维码
- Thinkphp3.2.3 关联模型 一对多 数据写入和更新详解
- 解决JSP自动生成彩色验证码的问题
- 解决R.java无法自动生成id的问题
- 解决hibernate5不能自动生成表的问题
- ThinkPHP3.0,成功解决接收checkbox值的问题
- Thinkphp3.2中解决插入相同数据的问题
- ThinkPHP3.2.1有关自动生成以及控制器
- thinkphp3.1.3多对多关联模型BUG修复
- 解决matlab2012安装时快捷方式和.m文件自动关联的问题
- 解决matlab2012安装时快捷方式和.m文件自动关联的问题(太有用了)
- KVC字典转模型以及常见错误解决(接上昨晚的自动生成属性)
- Echart 饼状图,柱状图series.data数据动态设置
- Oracle创建directory
- 什么是TLB ?
- Linux升级openssh及问题总结
- 高德地图之定位篇----->定位、预测天气、围栏、搜索周边、行踪轨迹
- Thinkphp3.2.3 解决关联模型的自动生成问题($_auto)
- 在linux上使用tomcat
- android触摸事件分发机制
- 虚拟机VMware3种网络模式
- 广播与服务
- SpringMVC返回json数据的配置方式
- 【Qt】QT之中多个信号连接同一个槽【细说版】
- okHttp使用及优缺点
- Oracle建立表空间和用户