一、概述
ThinkPHP的官方叫法是自动验证、自动完成和字段映射,由于这三项功能都是使用create()方法时自动实现的,所以个人称之为三大自动,即自动验证、自动完成(自动填充)和自动映射
二、自动验证
类型检查只是针对数据库级别的验证,所以系统还内置了数据对象的自动验证功能来完成模型的业务规则验证,而大多数情况下面,数据对象是由表单提交的$_POST数据创建。需要使用系统的自动验证功能,只需要在Model类里面定义$_validate属性,是由多个验证因子组成的数组,一个验证因子就是一个一维数组,也就是说在自定义Model类中定义的$_validate属性是一个二维数组
强调一下,自动验证针对的是表单的name属性,而不是数据对象,也不是实际的数据表字段。数据对象中相应的属性和数据表相应字段是一致的!
所谓自动验证,就是在根据用户的输入(通常是POST过来的表单)创建了数据对象之前,自动对传过来的数据进行验证(比如说用户名长度、重复密码与密码是否一致、邮箱格式是否合法等等),以获取到合法的数据。通常这些操作需要手动(在控制器中)写代码进行处理,但是ThinkPHP为我们提供了一种更好的解决方案,即在create()方法中自动实现!
1、验证因子格式
array(验证字段,验证规则,错误提示,验证条件,附加规则,验证时间)
·验证字段(必须)
如果没做自动映射,那么验证字段就必须是表单的name属性值;如果做了自动映射,那么验证字段就是映射之后的值!特别强调一点,自动映射成哪个值(即便是与数据表字段名不相同)都并不会影响自动验证,但是会影响数据对象的创建(这里影响数据对象的创建并不是说创建失败而是指自动映射的那个与数据表字段不相同的值并不会压入到数据对象中,即数据对象不完整),所以一般来说,自动映射成的那个值就是数据表实际字段名,以便于数据对象的创建!
验证字段并不是必须得存到数据表中的,也可以是表单的一些辅助,如确认密码、验证码等等
·验证规则(必须)
要进行验证的规则,得结合附加规则
·错误提示(必须)
用于验证失败后的提示信息
·验证条件(可选)
Model::EXISTS_TO_VAILIDATE或者0,表示存在就验证(默认)。即如果该字段存在就验证
Model::MUST_TO_VALIDATE或者1,必须验证。即不管字段是否存在,都得验证
Model::VALUE_TO_VAILIDATE或者2,值不为空的时候验证。即该字段传递过来的数据不为空就验证
·附加规则(可选)
配合验证规则使用
regex表示使用正则进行验证,那么前面的验证规则就必须是一个正则表达式(默认)
系统内置了一些正则规则,可直接使用,比如require(不能为空)、email(邮箱)、url(URL地址)、 currency(货币)、number(数字)
同时也可以自定义正则表达式或Google
function表示使用函数进行验证,那么前面的验证规则就必须是一个函数
callback表示使用方法进行验证,那么前面的验证规则就必须是当前模型类的一个方法
confirm表示验证两个字段值是否相同,那么那么前面的验证规则就必须是一个字段
equal表示验证是否等于某个值,那么前面的验证规则就必须是一个值
in表示验证是否在某个范围内,那么前面的验证规则就必须是一个数组
unique表示验证是否唯一,系统会根据传递过来的值去查询数据库,如果存在,则报错并终止
·验证时间(可选)
Model:: MODEL_INSERT 或者1,表示新增数据时候验证
Model:: MODEL_UPDATE 或者2,表示编辑数据时候验证
Model:: MODEL_BOTH 或者3,表示全部情况下验证(默认)
2、所有的验证因子验证成功才算验证成功,且验证成功之后才创建数据对象(创建成功返回一个数组),否则不创建(创建失败返回false)!
3、错误提示是通过$Model->getError()方法获取到的
4、一般来说,一个表的验证规则是固定的,但是有些特殊情况下也需要改变验证规则,但是出于安全性考虑,$_validate属性通常定义为private或protected的,无法直接通过对象访问。鉴于此,ThinkPHP设计了一个public的setProperty()方法可以修改对象属性
显然,如果$_validate属性是public的话,可以直接修改,但是一般是不会定义成public的!
如下是ThinkPHP源码的Model类中的setProperty()方法的定义,其中property_exists()函数(原生php函数)检测一个对象或类是否有某个属性
三、自动完成(自动填充)
所谓自动完成(自动填充),就是在根据用户的输入(通常是POST过来的表单)创建了数据对象之后,自动再给该数据对象添加其它的属性或对已有的属性进行后续处理(比如说对密码进行MD5加密处理),以适应实际的数据表字段。因为有些数据表字段(比如说用户注册时间、注册IP)的值不能或不必由用户输入,而是能或必须由系统生成。通常这些由系统生成的值或后续处理需要手动(在控制器中)写代码进行处理,但是ThinkPHP为我们提供了一种更好的解决方案,即在create()方法中自动实现!
通过$_auto属性是由多个填充因子组成的数组,而一个填充因子也是一个数组,故$_auto属性是一个二维数组
1、填充因子格式
array(填充字段,填充内容,填充条件,附加规则)
·填充字段
填充字段理论上可以是任何值,但是实际开发中,一般有两种情况,一是数据对象中已有的(因为自动完成是在创建数据对象之后),以进行后续处理(比如说md5加密处理);二是数据对象中没有但数据表中有的实际字段(说的准确点,应该是不能为null的字段),以给该数据对象添加可以插入到数据表的属性!
与自动验证的验证字段区别开
从第一种情况可以看出,自动完成实际上是可以覆盖表单的提交项目的!
·填充内容(填充规则)
同样必须得配合附加规则一起使用
·填充条件
同验证因子验证时间含义
Model:: MODEL_INSERT 或者1 新增数据的时候处理(默认)
Model:: MODEL_UPDATE 或者2更新数据的时候处理
Model:: MODEL_BOTH 或者3所有情况都进行处理
·附加规则
function表示填充内容是一个函数
callback表示填充内容是当前模型类的一个方法
field表示填充内容是其它一个字段的值
string表示填充内容是一个字符串(默认)
2、同自动验证一样,也是可以setProperty()方法动态修改自动完成规则的
3、与自动验证不同,自动完成的function或callback返回值就是填充因子的填充内容,而自动验证的function或callback返回值是一个布尔值
四、自动映射
所谓自动映射,就是在根据用户的输入(通常是POST过来的表单)创建了数据对象之前,自动的将表单相关控件name属性值映射成数据表中相应字段名,以便于创建数据对象。因为如果用于创建数据对象的数组(通常是$_POST)中的元素键在实际的数据表中找不到相同的字段名,那么该元素就不会被添加到数据对象中。通常这个映射的操作需要手动(在控制器中)写代码进行处理(如下),但是ThinkPHP也为我们提供了一种更好的解决方案,即在create()方法中自动实现!
有人会说,这么麻烦干嘛咧,直接将表单中的name属性值写成与数据表中实际字段名一样不就可以了吗?其实这种做法功能上是可以的,但是不安全!因为这样做的话,用户就可以通过name属性值知道数据表中的实际字段名,从安全的角度来看,这种做法是不可取的!