模型获取器 getFieldNameAttr
获取器是写在模型类中的一个方法,对模型实例的原始数据做出自动处理,当用户通过模型获取表中数据时会自动触发。
获取器应用场景:用于从数据表中读取数据:
时间日期字段的格式化输出; 2.集合或枚举类型的输出; 3.数字状态字段的输出; 4.组合字段的输出
获取器方法命名规则:get字段名Attr(字段值[,所有字段]) 例如: getNameAttr($value)
获取器还可以读取不存在的字段信息
配置文件:app\index\model\Staff.php
//获取器1: 常见sex字段,仅限模型内部调用,不能是public protected function getSexAttr($value) { $sex = [0=>'男', 1=>'女']; return $sex[$value]; }
控制器文件:app\index\controller\Operate.php
<?php namespace app\index\controller; use think\Controller; use app\index\model\Staff; class Operate extends Controller { //获取器1:gain() public function gain() { $res = staff::get(10); //实例并初始化staff模型 dump($res); //查看所有字段信息 echo '<hr color="red">'; echo $res->sex,'<br>'; //查看经过修改器处理后的性别字段 echo $res->name.'的性别是: '.$res->getData('sex') .' (原始数值)'. '<br>'; //查看原始字段值 echo '<hr color="red">'; } }
配置文件:app\index\model\Staff.php
//获取器2: 可传入所有字段的值,用来更加完整的描述用户字段信息 protected function getSalaryAttr($value, $data) { return $data['name'].'的年薪是:'.($value*12); //生成用户订单是常用操作 } protected function getAgeAttr($value, $data) { return $data['name'].'的虚岁是: '.($value+1); //生成用户订单是常用操作 }
控制器文件:app\index\controller\Operate.php
public function gain() { $res = staff::get(35); //实例并初始化staff模型 // dump($res); //查看所有字段信息 // echo '<hr color="red">'; echo $res->sex,'<br>'; //查看经过修改器处理后的性别字段 echo $res->name.'的性别是: '.$res->getData('sex') .' (原始数值)'. '<br>'; //查看原始字段值 echo '<hr color="red">'; echo $res->age.' 岁'.'<br>'; //查看经过修改器处理后的虚岁值 echo $res->name.'的周岁是: '.$res->getData('age').' 岁' .' (原始数值)'. '<br>'; //查看原始字段值 echo '<hr color="red">'; echo $res->salary.' 元'. '<br>'; ////查看经过修改器处理后的工资字段(工资按12倍计算,即12个月的工资) echo $res->name.'的月薪是: '.$res->getData('salary').' 元'. '<br>'; //查看原始字段值(工资按每月计算) echo '<hr color="red">'; }
配置文件:app\index\model\Staff.php
//获取器3: 可以为表中不存在的字段设置获取器方法,纯粹为了拼装字段内容 protected function getStaffInfoAttr($diy, $data) { //其实$value此时仅是一个占位符,可任意命名,无任何意义 return '我的名字叫:'.$data['name'].', 年龄:'.$data['age'].' 岁'.', 月薪:'.$data['salary'].' 元'.', 刚刚够养家了~`'; }
控制器文件:app\index\controller\Operate.php
public function gain() { $res = staff::get(35); //实例并初始化staff模型 echo $res->staff_info, '<br>'; //查看一个不存在的字段信息 echo '<hr color="green">'; }
//获取器:gain() public function gain() { $staffs = staff::all(); //获取所有员工信息 echo '<table border="1" cellspacing="0" align="center" width="80%">'; echo '<caption><h4>员工信息表</h4></caption>'; foreach ($staffs as $staff) { echo '<tr>'; echo '<td align="center">'.'姓名: '.$staff->name.'</td>'; echo '<td align="center">'.'性别: '.$staff->sex.'</td>'; echo '<td align="center">'.'年龄: '.$staff->getData('age').'</td>'; echo '<td align="center">'.'工资: '.$staff->getData('salary').' 元'. '</td>'; } echo '</tr>'; }
模型修改器 setFieldNameAttr
修改器也是模型类中的一个方法,对模型设置的数据对象值进行处理。
修改器的使用场景和读取器类似:
1.时间日期字段的转换写入; 2.集合或枚举类型的写入; 3.数字状态字段的写入; 4.某个字段涉及其它字段的条件或者组合写入
以下5种情况下会触发修改器工作:
1.模型对象赋值; 2.调用模型的data方法,并且第二个参数传入true; 3.调用模型的save方法,并且传入数据;
4.显式调用模型的setAttr方法; 5.定义了该字段的自动完成;
配置文件:app\index\model\Staff.php
//修改器:支持传入第二个参数,引用其它字段的值 protected function setSalaryAttr($value, $data) { //salary字段存入表中时,自动减去员工的年龄 return $value-$data['sex']; }
控制器文件:app\index\controller\Operate.php
public function modify() { $res = Staff::get(3); $res->salary = 8800; $res->save(); return '修改成功'; }
模型类型转换
支持给字段设置类型自动转换,会在写入和读取的时候自动进行类型转换处理
配置文件:app\index\model\Staff.php
protected $type = [ 'staff_id' => 'integer', 'sex' => 'integer', 'age' => 'interger', 'salary' => 'interger', ];
数据库查询默认取出来的数据都是字符串类型,如果需要转换为其他的类型,需要设置
支持的类型包括的类型:
integer : 该字段写入和输出的时候都会自动转换为整型。
float : 该字段的值写入和输出的时候自动转换为浮点型。
boolean : 该字段的值写入和输出的时候自动转换为布尔型。
array : 设置为此类型,系统会自动把数组编码为json格式字符串写入数据库,取出来的时候会自动解码。
object : 该字段的值在写入的时候会自动编码为json字符串,输出的时候会自动转换为 stdclass 对象。
serialize : 指定为序列化类型,数据会自动序列化写入,并且在读取的时候自动反序列化。
json : 指定为 json 类型,数据会自动 json_encode 写入,并且在读取的时候自动 json_decode 处理。
timestamp : 指定为时间戳字段类型的话,该字段的值在写入时候会自动使用 strtotime 生成对应的时间戳,输出的
时候会自动转换为 dateFormat 属性定义的时间字符串格式,默认的格式为 Y-m-d H:i:s
自动完成:针对写操作:新增和更新 相当于给字段添加默认值
配置文件:app\index\model\Staff.php
protected $insert = ['sex' => 0,'salary'=> 1000]; //新增时 protected $update = ['sex'=> 0]; //更新时 protected $auto = ['sex'=>0]; //针对新增和更新同时有的值时 类似二合一 一般都用这个
//自动完成: public function auto() { Staff::create(['name'=>'玉帝','age'=>20000]); }
模型自动时间戳 添加与更新数据时,将时间自动写入到指定字段中
自动时间戳 可以全局开启,也可以在模型中单独开启
1. 全局设置:config/database.php
// 自动写入时间戳字段 'auto_timestamp' => false, //改为true
如果当前模型中不需要自动时间戳功能,请手动关闭
protected $autoWriteTimestamp = false;
2. 模型设置:
protected $autoWriteTimestamp = true;
建议在模型中单独开启,这样最灵活,毕竟不是每一张表都需要时间戳字段
//修改器:将入职时间自动转为时间戳存储 protected function setEntryTimeAttr($value) { return strtotime($value); }
strtotime 支持将日期时间格式(如:2018-2-10) 转换为一串安全的时间戳
//修改器: 先给staff表新增一个字段entry_time: 入职时间 public function modify() { $res = Staff::get(2); $res->entry_time = '2018-04-22'; $res->save(); return '修改成功'; }
以下是开启自动时间戳功能,为了让数据添加或修改数据的同时,自动生成记录添加或修改的时间
//开启当前模型的自动时间戳功能 protected $autoWriteTimestamp = true; //设置支持自动时间戳功能的字段名 protected $createTime = 'create_time'; protected $updateTime = 'update_time';
当数据中有哪些时间戳字段,就需要手动开启一下相关字段的时间戳功能
数据验证技术
用户提交的请求数据,以及要写到数据表的数据,必须是符合要求的,安全的,所以,对于外部提交的数据,必须进行验证,这是Web开发的第一原则
数据验证技术有二种方式:
验证器类:创建与模型对象的验证器类,类文件与位置都可以自定义,建议验证器名与模型同名
1. 在application下创建validate目录,并创建一个与数据库中各个表同名的类文件。
例如:staff表 : Staff.php 表示validate/Staff.php 专门验证数据库staff表的数据
2. application/validate/Staff.php: 就是我们要创建的验证器类
写两个信息:验证规则和错误信息
<?php namespace app\validate; 引入框架验证类 use think\Validate; class Staff extends Validate { //创建验证规则 //以属性的方式进行配置,属性不能更改 protected $rule = [ 'name'=>'require|min:3|max:21', 'sex' => 'in:0,1', 'age' => 'require|between:14,80', 'salary' => 'require|gt: 2500' ]; //错误信息可以自定义: protected $message = [ 'name.require' => '员工姓名不能为空', 'name.min' => '姓名不能少于3个字符', 'name.max' => '姓名不能大于21个字符', 'sex.in' => '性别只能选择男或女', 'age.require' => '年龄必须输入', 'age.between' => '年龄必须在14到80周岁之间', 'salary.require' => '工资必须输入', 'salary.gt' => '工资必须大于2500元' ]; }
1. 直接实例化验证器完成验证
<?php namespace app\index\controller; use think\Controller; //导入框架验证类 use app\validate\Staff; //导入验证器 use think\Validate; class Verify extends Controller { //验证器: 直接实例化验证器完成验证 public function demo1() { //准备要验证的数据 $data = [ 'name'=>'太上老君', 'sex' => 1, 'age' => 99, 'salary' => 9200 ]; //开始验证 $validate = new Staff(); if (!$validate->check($data)) { dump($validate->getError()); } else { return '验证通过'; } //简化版验证 $rule = 'app\validate\Staff'; $res = $this->validate($data,$rule); if (true !== $res) { //验证成功返回true,否则返回错误信息 return $res; } return '验证成功'; } }
2. 使用控制器内容的验证对象来完成验证: $this->validate($data, $rule)
public function demo2() { //准备要验证的数据 $data = [ 'name'=>'太白金星', 'sex' => 0, 'age' => 2225, 'salary' => 16600 ]; $rule = 'app\validate\Staff'; $rule = [ 'age' => 'between:1000,5000', ]; $message = [ 'age.between' => '年龄必须在10到5000之间' ]; $res = $this->validate($data,$rule,$message); if (true !== $res) { //验证成功返回true,否则返回错误信息 return $res; } return '验证成功'; }
当数据比较简单时 可以绕过验证器,直接在模型中验证
独立验证:实例化框架的think\Validate.php:主要是通过Validate::make()和check()进行验证
1. 创建验证规则 2. 创建错误信息 3. 创建验证数据
4. make($rule,$mess):创建验证规则与错误信息
5. check($data)完成数据验证
public function demo3() { //1.创建验证规则 $rule = [ 'age' => 'require|between:14,80' ]; //2.创建错误信息 $mess = [ 'age.require' => '年龄必须填写', 'age.between' => '年龄必须在14到80之间' ]; //3.创建验证数据 $data = ['age' => 10]; //初始化验证器类,并返回验证器实例 //make($rule,$mess):创建验证规则与错误信息 $validate = Validate::make($rule, $mess); //check($data)完成数据验证 $res = $validate->check($data); return $res ? '验证通过' : $validate->getError(); }