ThinkPHP5 select出来的结果是个对象?居然还可以以数组形式访问数据?
来源:互联网 发布:淘宝客怎么关闭掉 编辑:程序博客网 时间:2024/05/22 14:46
目录
- 目录
- 前言
- TP5中的select方法
- 为什么可以这么操作
- 总结
- 思考
前言
在使用TP5的过程中,我们会发现,使用select方法查询数据库中的数据后dump出来的结果是对应模型的对象。其中该对象有一个protected的data属性。而在TP3中select出来的结果返回的是一个数组。那么我们在使用TP5中select后得到了对应的结果——一个对象,怎么通过这个对象获取结果数据呢?
结果是同样可以以数组的方式获取数据。同TP3的操作。在模板输出中,同样也使用。那为什么呢?明明这个是一个对象不是什么数组呀,怎么可以以数组的方式访问结果集呢额?
参考:PHP中__get()和__set()的用法实例详解
PHP实现对象属性按数组方式访问
TP5中的select方法
【栗子】调用model创建Goods对应的模型,并使用select方法查询数据,将查询结果dump出来,如下:
public function test() { dump(model('Goods')->select()); }
运行结果如下:
这里可以看到它返回了一个数组,每个元素的值是一个Goods对象(它继承于Model类)。可以发现其protected的data属性保存着我们想要的结果集。我们获取结果集中的内容,同操作数组无异。如:
public function test() { //dump(model('Goods')->select()); $res = model('Goods')->select(); $goods = $res[0]; echo 'id:' . $goods['id'] . '<br/>'; echo 'name:' . $goods['name'] . '<br/>'; echo 'brief:' . $goods['brief'] . '<br/>'; }
运行结果如下:
为什么可以这么操作
既然select方法返回的对象继承于Model类,那其中的玄机一定来自这个Model类。
(可以先阅读一下,我上面提及的参考文正。)
首先,我们应该考虑,为什么一个对象可以以数组的形式访问。(要是一般情况下,这样去操作一个对象会报错的。)
扣一个Model类的源码,我们会发现Model实现了ArrayAccess接口,恰恰这就是奇妙的地方所在。实现了该接口,并实现了对象的抽象方法,那么对象就可以以数组形式访问对象内保存的某些数据。
Model类型实现ArrayAccess接口中的方法,如下:
// ArrayAccess public function offsetSet($name, $value) { $this->setAttr($name, $value); } public function offsetExists($name) { return $this->__isset($name); } public function offsetUnset($name) { $this->__unset($name); } public function offsetGet($name) { return $this->getAttr($name); }
我们这里先只考虑获取属性值,那么offsetGet方法就实现了
getArr的实现如下:
/** * 获取器 获取数据对象的值 * @access public * @param string $name 名称 * @return mixed * @throws InvalidArgumentException */ public function getAttr($name) { try { $notFound = false; $value = $this->getData($name); } catch (InvalidArgumentException $e) { $notFound = true; $value = null; } // 检测属性获取器 $method = 'get' . Loader::parseName($name, 1) . 'Attr'; if (method_exists($this, $method)) { $value = $this->$method($value, $this->data); } elseif (isset($this->type[$name])) { // 类型转换 $value = $this->readTransform($value, $this->type[$name]); } elseif ($notFound) { $method = Loader::parseName($name, 1); if (method_exists($this, $method) && !method_exists('\think\Model', $method)) { // 不存在该字段 获取关联数据 $value = $this->relation()->getRelation($method); // 保存关联对象值 $this->data[$name] = $value; } else { throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name); } } return $value; }
在getAttr方法中中主要获取值的方法又是getData方法。
getData方法如下:
/** * 获取对象原始数据 如果不存在指定字段返回false * @access public * @param string $name 字段名 留空获取全部 * @return mixed * @throws InvalidArgumentException */ public function getData($name = null) { if (is_null($name)) { return $this->data; } elseif (array_key_exists($name, $this->data)) { return $this->data[$name]; } else { throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name); } }
TMD发现了!!!getData方法返回的便是当前对象data属性对应的值。
总结
在这个过程中,最为关键的是Model类实现ArrayAccess接口。通过实现接口的方法,select出来的结果对象便可以通过数组的形式访问到我们想要的结果集,即对象的protected的data属性的内容。
思考
TP5中,在使用继承于Model的模型对象时,会经常发现,我们会使用到如:$model->id
的形式访问属性值,可是我们并没有在对应的模型类声明id属性呀。
同样地,玄机还是在于这个Model类。它含有__get、__set这样两个魔术方法:
/** * 修改器 设置数据对象的值 * @access public * @param string $name 名称 * @param mixed $value 值 * @return void */ public function __set($name, $value) { $this->setAttr($name, $value); } /** * 获取器 获取数据对象的值 * @access public * @param string $name 名称 * @return mixed */ public function __get($name) { return $this->getAttr($name); }
那么,原因我想你应该知道了。嘻嘻~
- ThinkPHP5 select出来的结果是个对象?居然还可以以数组形式访问数据?
- 把二进制的字段以字符串形式Select出来
- 把二进制的字段以字符串形式Select出来
- 获取BMP图像的数据(以数组矩阵形式读取出来)&&将数组矩阵数据转成BMP图像
- 【php语法】实现ArrayAccess接口,以数组的形式访问对象
- 以指针的形式和以下标的形式访问指针?以指针的形式和以下标的形式访问数组?
- 以数组形式获取数据
- 以对象形式处理数据
- 将随机产生10个数的集合转成数组,并以数组的形式显示出来
- 使用该JavaBean可以将数据在JSP页面中以表格的形式显示出来,并具有动态排序、动态生成查询、自动分页功能
- 现在的就业形式还可以
- MVC架构下将查询到的数据以表格形式展现出来
- 金额降序排序后如何以柱形图的形式将数据展现出来
- Postgres数据库是否可以存放数组形式的数据
- grails表单提交数据保存时,封装多个对象,以单一对象形式提交
- C# 以JSON数组形式返回数据
- “网站目录文件以列表的形式呈现出来”?
- 如何将mp3文件以列表的形式显示出来?
- Android属性动画完全解析(上),初识属性动画的基本用法
- noi-8175-将字符串中的小写字母转换成大写字母
- 下载网页视频
- jQuery的加法运算
- MyBatis参数传入集合之foreach动态sql
- ThinkPHP5 select出来的结果是个对象?居然还可以以数组形式访问数据?
- 手写数字识别系统编程技巧
- “谈一谈网络编程学习经验“总结
- MySQL简单实例
- 【Unity优化】为C#定制联合(Union)提高序列化速度
- hadoop自定义分区
- Codeforces 688E The Values You Can Make【Dp】
- springmvc知识点总结
- Android 性能优化之布局优化