# 间接读取数据之模型
直接读取数据由于直接使用sql语句来操作数据库以及不依赖于其它文件的特性,往往适用于一些`动态数据表`的情景。
也正是由于这些特性,直接读取数据方法将产生大量的sql语句。大量的sql语句编写也就意味着可能会产生更多的错误,更主要的是这种方法非常不灵活,不能够自动适应诸如数据表名称变更、字段名称变更等变更情况,也不能够适用于数据库类型的变更。
在实际的生产项目中,我们应当规避直接读取数据的方法,采用更加面向对象、更加灵活、适应性更强的`模型`。
>[success] 世界上没有永恒不变的事物,如果非要找一个,那就是变化。
# 数据模型
Model(模型)是个比个宽泛的概念,在这里我们单纯的指:某个与数据表存在对应关系的PHP类。在ThinkPHP中,通过继承`think\Model`来声明模型类。比如我们此时需要一个与数据表teacher存在对应关系的PHP类。则可以在新建如下模型类:
![](https://img.kancloud.cn/8f/6e/8f6eec8ada8e2be0a53e57ac78259fef_602x292.png)
我们习惯于将模型类的命名与数据表相统一,比如我们当前想建立与teacher表的对应关系,则命名为teacher.php;我们还习惯于使用首写字母大写的方式来表现这是一个`类`文件,所以我们将使用了`Teacher.php`而非`teacher.php`;我们还习惯于将所有的模型都放到`模型村`,所以我们在app文件夹下新建了`model`文件夹,并命名为`model`,我们此后将所有模型都放到当前model村里,这便于我们日后的查找。
>[info] 更多有经验的大牛前辈们养成的习惯,形成了我们小白应该遵守的**规范**。
## 类初始化
使用以下固有代码来初始化Teacher类:
```php
<?php ❶
namespace app\model; ❷
class Teacher ❸
{
}
```
* ❶ 声明当前文件类型为php。
* ❷ 若要让其它对象通过`/命名空间/类名`的方式找到它,除了要将其文件对应放到命名空间对应的文件夹中,还需要该文件本身认同自己位于当前命名空间中。
* ❸ 定义与文件名相同的同名Teacher类,首字母大写。
### 测试
我们在前面的章节使用了住在`\think\facade\`中的Db类来查找数据,当然也可以使用同样的方法来尝试找住在`app\model`中的`Teacher`。
打开`controller/Index.php`,删除原`index()`方法中的代码,并加入以下代码:
```php
class Index extends BaseController
{
public function index()
{
// 找app\model命名空间的Teacher来帮忙
$teacher = new \app\model\Teacher();
dump($teacher);
}
```
* Teacher类中并没有类似于Db类中的query方法,没有办法使用类似于Db::query()的方法测试。我们在此使用new一个新对象的方式来测试是否能够成功找到Teacher类。
* 在PHP中,new对象时可以不加括号。`new \app\model\Teacher()`等价于`new \app\model\Teacher`
* 使用`dump()`函数可以查看一切变量
![](https://img.kancloud.cn/81/70/8170ea9d14b9d97f115dd148e1937aec_379x105.png)
>[success] TIPS:永远不要想当然,测试永远是重要的一环。
## 获取所有教师
ThinkPHP提供了一个住在`\Think`村的`Model`来帮助我们快速的实现数据的增改查删。面向对象有一个重大的特性叫`继承`。大体就是说:儿子是可以在老子允许的范围内随意使用老子的资源的。当前我们需要查询`teacher`中的所有数据,则可以在`model/Teacher.php`中声明继承`\Think\Model`:
```php
<?php
namespace app\model;
class Teacher extends \Think\Model
{
}
```
此时做为儿子的`Teacher`便可以使用老子`\Think\Model`中的任意资源了。这其中的`select()`方法便可以对应获取`teacher`表中的所有数据:
```php
public function index()
{
// 找app\model命名空间的Teacher来帮忙
$teacher = new \app\model\Teacher();
// 获取teacher表中的所有数据
$teachers = $teacher->select();
dump($teachers);
}
```
刷新浏览器测试,可以看到返回值`$teachers`的类型为`think\model\Collection`,该类型中存在一个名为`items`的属性,属性的值是一个拥有2项数据的数组,每项数据的类型都是我们定义的`app\model\Teacher`
>[info] `think\model\Collection`可以暂时理解为一个集合(数组),该类型为ThinkPHP提供。可以像PHP原生数组一样使用。
```
^ think\model\Collection {#60 ▼
#items: array:2 [▼
0 => app\model\Teacher {#55 ▶❶}
1 => app\model\Teacher {#59 ▶}
]
}
```
在浏览器中点击❶,将第0个数据展开后可以于`data`属性中查看到数据表中对应的值:
```
0 => app\model\Teacher {#55 ▼
...
-data: array:7 [▼
"id" => 1
"name" => "张三"
"sex" => 0
"username" => "zhangsan"
"email" => "zhangsan@mail.com"
"create_time" => "1970-01-02 18:12:03"
"update_time" => "1970-01-02 18:13:33"
]
...
```
至此为止,我们成功地将teacher表中的数据查询到php代码中,并使用`dump`方法确认了查询后的数据。即解决了第2个知识盲点:成功连接数据库后如何查询teacher数据表。
接下来我们共同解决最后一个知识盲点:如何将接收到的teacher表中的数据转换为html
# 本节作业
1. 猜测试一下`\Think\Model`中的`select()`方法是如何知道要查询的是`teacher`表,而非其它数据表的
2. 与上节相比较,同样是查询数据表中的所有数据,请总结查询结果的异同点
# 相关资源
| 内容 | 地址 |
| ----------- | ----------- |
| 模型--查询 | [https://www.kancloud.cn/manual/thinkphp6_0/1037585](https://www.kancloud.cn/manual/thinkphp6_0/1037585)|
| 本节源码 | [https://github.com/mengyunzhi/tp6/archive/step2.2.4.zip](https://github.com/mengyunzhi/tp6/archive/step2.2.4.zip) |
- 序言
- 第一章 Hello World
- 1.1 运行环境
- 1.1.1 windows
- 1.1.2 macos
- 1.1.3 ubuntu
- 1.2 Hello ThinkPHP
- 1.2.1 windows
- 1.2.2 macos
- 1.2.3 ubuntu
- 2.3 Hello World
- 第二章 教师管理
- 2.1 数据库初始化
- 2.2 CRUD之 R 读取数据
- 1 数据流
- 2.2.2 连接数据库
- 2.2.3 直接读取数据之DB
- 2.2.4 间接读取数据之模型
- 2.2.5 显示数据之原始文案
- 2.2.6 单引号与双引号
- 2.2.7 显示数据之视图
- 2.2.8 模板语法
- 2.2.9 使用bootstrap美化界面
- 2.3 CRUD之 C 增加数据
- 2.3.1 MCA默认路由