# 间接读取数据之模型 直接读取数据由于直接使用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) |