您好,欢迎访问一九零五行业门户网

关于Thinkphp框架视图模型调用的一些有关问题总结

关于thinkphp框架视图模型调用的一些问题总结
对于tp框架中视图模型的调用在项目中比较常用,这次的毕业设计中对于碰到了一些问题写下总结:
?
一、自定义dao的orm的model定义在视图调用时出现异常
?
当把model定义成形如
class usermodel extends model { private $ormobj; /** * * 构造函数 */ function __construct(){ $this->ormobj=m('user'); }}
然后是视图模型的定义:
class mentionviewmodel extends viewmodel { public $viewfields = array( 'mention'=>array('id','tid','uid'), 'topic' => array('create_time','from'=>'topic_from','content','status','_on'=>'mention.tid=topic.id'), 'user' => array('nickname','homepage','avatar','_on'=>'topic.uid=user.id') ); }
而输出的sql语句确是:
select mention.id as id,mention.uid as uid,mention.tid as tid,topic.create_time as create_time,topic.from as topic_from,topic.content as content,user.avatar as avatar,user.nickname as nickname,user.homepage as homepage from fl_mention mention join topic on mention.tid=topic.id join user on topic.uid=user.id where topic.status=1 and mention.uid=1 order by mention.id desc limit 0,20
?对于要取别名的表名丢失了,这种dao式的orm调用时在视图模型中会出现找不到表名的情况。
?
在父类viewmodel中有这样一个函数,是提取表名的:
public function gettablename() { if(empty($this->truetablename)) { $tablename = ''; foreach ($this->viewfields as $key=>$view){ // 获取数据表名称 $class = $key.'model'; $model = class_exists($class)?new $class():m($key); $tablename .= $model->gettablename(); // 表别名定义 $tablename .= !empty($view['_as'])?' '.$view['_as']:' '.$key; // 支持on 条件定义 $tablename .= !empty($view['_on'])?' on '.$view['_on']:''; // 指定join类型 例如 right inner left 下一个表有效 $type = !empty($view['_type'])?$view['_type']:''; $tablename .= ' '.strtoupper($type).' join '; $len = strlen($type.'_join '); } $tablename = substr($tablename,0,-$len); $this->truetablename = $tablename; } return $this->truetablename; }
这里函数看到会去调用该类的超类model的 $model->gettablename() 这个函数:
?
public function gettablename() { if(empty($this->truetablename)) { $tablename = !empty($this->tableprefix) ? $this->tableprefix : ''; if(!empty($this->tablename)) { $tablename .= $this->tablename; }else{ $tablename .= parse_name($this->name); } $tablename .= !empty($this->tablesuffix) ? $this->tablesuffix : ''; if(!empty($this->dbname)) $tablename = $this->dbname.'.'.$tablename; $this->truetablename = strtolower($tablename); } return $this->truetablename; }
这个函数中这个语句empty($this->truetablename)便是提取表名的
下面给出解决方案一:
class usermodel extends model { protected $truetablename = 'fl_user'; private $ormobj; /** * * 构造函数 */ function __construct(){ $this->ormobj=m('user'); }}
?在该类中加入protected $truetablename = 'fl_user'; 这个属性使触发gettablename函数时可以找到对应的表名;
解决方案二:
function __construct(){ parent::__construct(); $this->ormobj=m('user'); }
?在子类中将覆盖掉的父类构造函数重新引入
?
?
?
?
二、自连接表的视图模型调用:
?
形如:
class topicviewmodel extends viewmodel { public $viewfields = array( 'topic'=>array('id'=>'root_id','content'=>'root_content'), 'topic' =>array('id'=>'topic_id','create_time','from'=>'topic_from','content','status','_on'=>'topic.id=topic.rootid') ); }
上面的语句执行的sql如下:
select topic.id as root_id,topic.id as topic_id from fl_topic topic join fl_topic topic on topic.id=topic.rootid
这句sql语句的错误很明显:因为sql是不区分大小写的,所以会直接报not unique table/alias: 'topic'的错误。
?
继续来看这个函数:
public function gettablename() { if(empty($this->truetablename)) { $tablename = ''; foreach ($this->viewfields as $key=>$view){ // 获取数据表名称 $class = $key.'model'; $model = class_exists($class)?new $class():m($key); $tablename .= $model->gettablename(); // 表别名定义 $tablename .= !empty($view['_as'])?' '.$view['_as']:' '.$key; // 支持on 条件定义 $tablename .= !empty($view['_on'])?' on '.$view['_on']:''; // 指定join类型 例如 right inner left 下一个表有效 $type = !empty($view['_type'])?$view['_type']:''; $tablename .= ' '.strtoupper($type).' join '; $len = strlen($type.'_join '); } $tablename = substr($tablename,0,-$len); $this->truetablename = $tablename; } return $this->truetablename; }
上面的函数对于前面的‘topic’索引只是做了工厂方式的模型生成。而其中的class_exists是不区分大小写的,而数组的索引是区分大小写的,我们可以利用这个特性,把同一个表的引用用仅大小写不同的索引表示
再在后面跟上_as属性即可:
?
下面代码:
public $viewfields = array( 'topic'=>array('id'=>'root_id','content'=>'root_content','_as'=>'root_topic'), 'topic' => array('id'=>'topic_id','create_time','from'=>'topic_from','content','status','_on'=>'root_topic.id=topic.rootid') );
?这样便可得到正确的sql语句了
select root_topic.id as root_id,topic.id as topic_id from fl_topic root_topic join fl_topic topic on root_topic.id=topic.rootid
?
tp的确是国内一款少有的成熟的框架~~但有些地方还是要用些另类的技巧来使用,自连接表的视图模型使用总觉得还是比较尴尬的,期待有更好的方式可以达到自连接的目的
?
其它类似信息

推荐信息