# 間接讀取數據之模型
直接讀取數據由于直接使用sql語句來操作數據庫以及不依賴于其它文件的特性,往往適用于一些`動態數據表`的情景。
也正是由于這些特性,直接讀取數據方法將產生大量的sql語句。大量的sql語句編寫也就意味著可能會產生更多的錯誤,更主要的是這種方法非常不靈活,不能夠自動適應諸如數據表名稱變更、字段名稱變更等變更情況,也不能夠適用于數據庫類型的變更。
在實際的生產項目中,我們應當規避直接讀取數據的方法,采用更加面向對象、更加靈活、適應性更強的`模型`。
>[success] 世界上沒有永恒不變的事物,如果非要找一個,那就是變化。
# 數據模型
Model(模型)是個比個寬泛的概念,在這里我們單純的指:某個與數據表存在對應關系的PHP類。在ThinkPHP中,通過繼承`think\Model`來聲明模型類。比如我們此時需要一個與數據表teacher存在對應關系的PHP類。則可以在新建如下模型類:

我們習慣于將模型類的命名與數據表相統一,比如我們當前想建立與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()`函數可以查看一切變量

>[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. 與上節相比較,同樣是查詢數據表中的所有數據,請總結查詢結果的異同點
# 相關資源
| 內容 | 地址 |
| ----------- | ----------- |
| 模型--查詢 | [http://www.hmoore.net/manual/thinkphp6_0/1037585](http://www.hmoore.net/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默認路由