关于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的确是国内一款少有的成熟的框架~~但有些地方还是要用些另类的技巧来使用,自连接表的视图模型使用总觉得还是比较尴尬的,期待有更好的方式可以达到自连接的目的
?

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Many users will choose the Huawei brand when choosing smart watches. Among them, Huawei GT3pro and GT4 are very popular choices. Many users are curious about the difference between Huawei GT3pro and GT4. Let’s introduce the two to you. . What are the differences between Huawei GT3pro and GT4? 1. Appearance GT4: 46mm and 41mm, the material is glass mirror + stainless steel body + high-resolution fiber back shell. GT3pro: 46.6mm and 42.9mm, the material is sapphire glass + titanium body/ceramic body + ceramic back shell 2. Healthy GT4: Using the latest Huawei Truseen5.5+ algorithm, the results will be more accurate. GT3pro: Added ECG electrocardiogram and blood vessel and safety

Why Snipping Tool Not Working on Windows 11 Understanding the root cause of the problem can help find the right solution. Here are the top reasons why the Snipping Tool might not be working properly: Focus Assistant is On: This prevents the Snipping Tool from opening. Corrupted application: If the snipping tool crashes on launch, it might be corrupted. Outdated graphics drivers: Incompatible drivers may interfere with the snipping tool. Interference from other applications: Other running applications may conflict with the Snipping Tool. Certificate has expired: An error during the upgrade process may cause this issu simple solution. These are suitable for most users and do not require any special technical knowledge. 1. Update Windows and Microsoft Store apps

Part 1: Initial Troubleshooting Steps Checking Apple’s System Status: Before delving into complex solutions, let’s start with the basics. The problem may not lie with your device; Apple's servers may be down. Visit Apple's System Status page to see if the AppStore is working properly. If there's a problem, all you can do is wait for Apple to fix it. Check your internet connection: Make sure you have a stable internet connection as the "Unable to connect to AppStore" issue can sometimes be attributed to a poor connection. Try switching between Wi-Fi and mobile data or resetting network settings (General > Reset > Reset Network Settings > Settings). Update your iOS version:

php提交表单通过后,弹出的对话框怎样在当前页弹出php提交表单通过后,弹出的对话框怎样在当前页弹出而不是在空白页弹出?想实现这样的效果:而不是空白页弹出:------解决方案--------------------如果你的验证用PHP在后端,那么就用Ajax;仅供参考:HTML code

Steps for kafka to create a topic: 1. Install and configure Kafka; 2. Create a Topic; 3. Verify Topic creation; 4. Configure Topic parameters; 5. Consider using Kafka Manager or Confluent Control Center; 6. Precautions. Detailed introduction: 1. Install and configure Kafka. First, make sure that Kafka has been installed correctly and that it is running. According to the needs and environment, configure the parameters of Kafka, etc.

A colleague got stuck due to a bug pointed by this. Vue2’s this pointing problem caused an arrow function to be used, resulting in the inability to get the corresponding props. He didn't know it when I introduced it to him, and then I deliberately looked at the front-end communication group. So far, at least 70% of front-end programmers still don't understand it. Today I will share with you this link. If everything is wrong If you haven’t learned it yet, please give me a big mouth.

Watch4pro and gt each have different features and applicable scenarios. If you focus on comprehensive functions, high performance and stylish appearance, and are willing to bear a higher price, then Watch 4 Pro may be more suitable. If you don’t have high functional requirements and pay more attention to battery life and reasonable price, then the GT series may be more suitable. The final choice should be decided based on personal needs, budget and preferences. It is recommended to carefully consider your own needs before purchasing and refer to the reviews and comparisons of various products to make a more informed choice.

This article will help you interpret the vue source code and introduce why you can use this to access properties in various options in Vue2. I hope it will be helpful to everyone!
