在ThinkPHP5的使用过程中,很多使用者刚接触到数据库操作时,不能很好调用相关的方法进行数据库的交互。下面就分享一下ThinkPHP5中Db与模型的区别
关于db与model的选择
使用DB方式是直接获取到的query类(ThinkPHP5/library/think/db/Query.php)的对象进行数据库的操作提供了基本的数据库curd操作功能。
使用model的方式是通过获取到模型对象然后在调用query类下的方法进行数据操作,但是在TP中的模型基类中还提供了较多的其他的方法可以方便使用例如获取器、修改器、数据完成等等功能。因此模型的功能更为强大
就数据格式而言,在DB中是采用的数组格式使用。而在模型中统一使用对象。其中数据库交互后涉及到格式转换。因此在同等情况下db的数据略快与模型方式。
因此对于ThinkPHP5使用DB与model的方式具体在编程中选择哪一个按照个人的观点并无强制要求。有时候为了项目中的封装采用模型方式可能更为合适一些
DB数据库的操作
关于DB数据库操作具体如何执行下面使用一个操作的案例介绍
2.1、创建测试相关代码
①创建测试使用的数据表
CREATETABLE`tp_user`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`name`varchar()NOTNULLDEFAULT,
PRIMARYKEY(`id`)
)ENGINE=MyISAMDEFAULTCHARSET=utf8;
②写入测试数据
insertintotp_userVALUES(null,leo)
③配置好数据的连接
④创建一个测试的方法
⑤执行的结果
2.2、分析index方法中的执行过程
由于TP中的自动加载机制Db::name(‘user’)这段代码的执行会自动找到Db类(ThinkPHP55/library/think/Db.php)下的静态方法name执行
①查看name方法
在源码中无法找到有name方法的存在但是找到了一个__callstatic的魔术方法。该魔术方法可以在调用静态方法时自动的触发
②查看__callstatic方法
在该方法中使用call_user_func_array调用了当前类下connect方法并且传递了其他的参数其中$method为要调用的方法名称即name方法
③查看connect方法
对于该connect方法的作用就是用于获取对象数据库的操作对象,此处可以打印出得到的对象为think\db\connector\Mysql(ThinkPHP5/library/think/db/connector/Mysql.php)的对象。即在控制器中所执行的Db::name(‘user’)等价于使用think\db\connector\Mysql调用了name方法
④查看think\db\connector\Mysql对象
在该类下并未发现存在name方法以及魔术方法的存在。因此代码能够执行绝对在父类的Connection(ThinkPHP5/library/think/db/Connection.php)中
⑤在Connection类中查看name相关的方法
在该类下也并未发现存在name方法但是却找到了一个魔术方法__call
结果为
该魔术方法也是调用了自身类下的getQuery方法
⑥查看getQuery的方法
此代码执行最终就获取到了Query类的一个对象。
⑦查看query类下name方法
在name方法后返回了当前对象本身因此最终Db::name(‘user’)得到了一个query类的对象,在调用query下的find就找到了数据
模型数据库的操作
3.1、创建模型相关代码
①创建测试方法
②创建自定义的模型
③执行结果
3.2、分析index2方法中的执行过程
①model函数的执行
在控制器中model(‘User’)函数为ThinkPHP5自带的助手函数可以用于获取到自定义模型类的对象
此处是通过的Loader类调用了静态方法所获取到的对象。具体是否为真实的模型对象可以自行打印model(‘User’)所执行的结果
②调用get方法
由于自定义的模型为空并且继承了TP模型基类因此调用的为模型基类下的get方法
在源码中通过使用static::parseQuery调用最终得到了query的对象。到这里可以说明模型的数据操作其本质也是调用的query类下的方法所实现
关于模型与DB的转换
在使用ThinkPHP5的模型操作数据时可能由于各种非模型方法的调用导致直接转换为了query对象此后就不能调用模型方法了往往导致错误无法定位。其实在模型基类中存在__call与__callStatic这两个魔术方法。一旦调用了非模型方法就会自动触发得到一个query对象
①修改控制器下的测试代码
②在__Call方法处增加打印
③结果
目前所得到的为query的对象因此后续就不能再调用模型方法了。