第十一天:(6)输入和验证【模型和关联】

第十一天:(6)输入和验证【模型和关联】

表单提交

首先创建一个视图模板文件 application/index/view/user/create.html,内容如下:

<!doctype html><html><head><meta charset="UTF-8"><title>创建用户</title><style>body {    font-family:"Microsoft Yahei","Helvetica Neue",Helvetica,Arial,sans-serif;    font-size:16px;    padding:5px;
}.form{    padding: 15px;    font-size: 16px;
}.form .text {    padding: 3px;    margin:2px 10px;    width: 240px;    height: 24px;    line-height: 28px;    border: 1px solid #D4D4D4;
}.form .btn{    margin:6px;    padding: 6px;    width: 120px;    font-size: 16px;    border: 1px solid #D4D4D4;    cursor: pointer;    background:#eee;
}a{    color: #868686;    cursor: pointer;
}a:hover{
    text-decoration: underline;
}h2{    color: #4288ce;    font-weight: 400;    padding: 6px 0;    margin: 6px 0 0;    font-size: 28px;    border-bottom: 1px solid #eee;
}div{    margin:8px;
}.info{    padding: 12px 0;    border-bottom: 1px solid #eee;
}.copyright{    margin-top: 24px;    padding: 12px 0;  border-top: 1px solid #eee;
}</style></head><body><h2>创建用户</h2><FORM method="post" class="form" action="{:url('index/user/add')}">昵 称:<INPUT type="text" class="text" name="nickname"><br/>邮 箱:<INPUT type="text" class="text" name="email"><br/>生 日:<INPUT type="text" class="text" name="birthday"><br/><INPUT type="submit" class="btn" value=" 提交 "></FORM>
    <div class="copyright">
        <a title="官方网站" href="http://www.thinkphp.cn">ThinkPHP</a> 
        <span>V5</span> 
        <span>{ 十年磨一剑-为API开发设计的高性能框架 }</span>
    </div></body></html>

User控制器增加新的操作方法create如下:

// 创建用户数据页面
public function create(){    
    return view();
}

view方法是系统封装的助手函数用于快速渲染模板文件,这里没有传入模板文件,则按照系统默认的解析规则会自动渲染当前操作方法对应的模板文件,也就是默认视图目录(application/index/view)下面的user/create.html文件,所以如果改成下面的方式是相同的:

// 创建用户数据页面
    public function create(){    
        return view('user/create');
    }

并且修改之前的add方法如下:

// 新增用户数据
    public function add(){    
    $user = new UserModel;    
    if ($user->save(input('post.'))) {        
    return '用户[ ' . $user->nickname . ':' . $user->id . ' ]新增成功';
    } else {        
    return $user->getError();
    }
}

我们访问URL地址:

http://tp5.com/user/create

页面输出如图:

输入用户信息后,点击提交按钮:

页面显示结果为:

用户[ 流年:30 ]新增成功

表单验证

永远不要相信用户的数据,所以现在给表单提交添加数据验证。

我们添加一个User验证器,如下:

<?php
namespace app\index\validate;

use think\Validate;

class User extends Validate{    // 验证规则
    protected $rule = [        
        'nickname' => 'require|min:5',        
        'email'    => 'require|email',        
        'birthday' => 'dateFormat:Y-m-d',
    ];
}

User验证器添加了三个属性的验证规则,分别表示:

  • 昵称必须,而且最小长度为5

  • 邮箱必须,而且必须是合法的邮件地址

  • 生日可选,如果填写的话必须为 Y-m-d格式的日期格式

对属性可以使用多个验证规则,除非使用了require开头的规则,否则所有的验证都是可选的(也就是说有值才验证),多个验证之间用|分割,并且按照先后顺序依次进行验证,一旦某个规则验证失败,后续的规则就不会再进行验证(除非设置批量验证方式则统一返回所有的错误信息)。

更多的内置规则可以参考完全开发手册的内置规则一节。

如果我们的验证规则里面使用了|,为了避免混淆则必须用数组方式定义验证规则,验证规则定义修改如下:

<?php
namespace app\index\validate;
use think\Validate;
class User extends Validate{    // 验证规则
    protected $rule = [        
        'nickname' => ['require','min'=>5],        
        'email'    => ['require','email'],        
        'birthday' => ['dateFormat'=>'Y|m|d'],
    ];
}

然后对控制器的add方法则稍加修改,在save方法之前添加一个validate方法即可:

// 新增用户数据
    public function add(){    
        $user = new UserModel;    
        if ($user->validate(true)->save(input('post.'))) {        
            return '用户[ ' . $user->nickname . ':' . $user->id . ' ]新增成功';
        } else {        
            return $user->getError();
        }
    }

当我们没有输入任何表单数据就直接提交的话,页面会输出结果:

nickname不能为空

当我们输入昵称为wo的时候点击提交

页面输出结果为:

nickname长度不能小于 5

当输入一个错误的邮箱格式后提交

页面提示错误信息为:

email格式不符

当输入一个 1990/08/09 的生日时候

页面提示的错误信息是:

birthday必须使用日期格式:Y-m-d

错误提示

目前为止,提示的错误信息都是系统默认的,接下来我们来定义提示信息。

首先,如果只是希望修改属性名称的话,可以直接使用下面的验证规则定义方式:

<?php
namespace app\index\validate;

use think\Validate;
class User extends Validate{    
    // 验证规则
    protected $rule = [        
        'nickname|昵称' => 'require|min:5',        
         'email|邮箱'    => 'require|email',        
         'birthday|生日' => 'dateFormat:Y-m-d',
    ];
}

现在我们提交一个错误的邮箱,

提示的错误信息为:

邮箱格式不符

输入错误的生日格式的时候,提示的错误信息为:

生日必须使用日期格式:Y-m-d

如果希望完整定义错误提示信息的话,可以使用:

<?php
namespace app\index\validate;

use think\Validate;class User extends Validate{    // 验证规则
    protected $rule = [
        ['nickname', 'require|min:5', '昵称必须|昵称不能短于5个字符'],
        ['email', 'email', '邮箱格式错误'],
        ['birthday', 'dateFormat:Y-m-d', '生日格式错误'],
    ];
}

现在我们提交一个错误的邮箱,提示的错误信息为:

邮箱格式错误

提交一个错误的生日格式后,提示的错误信息变成:

生日格式错误

系统提供了丰富的内置验证规则,具体可以参考完全开发手册。

自定义验证规则

系统的验证规则可以满足大部分的验证场景,但有时候我们也需要自定义特殊的验证规则,例如我们需要验证邮箱必须为thinkphp.cn域名的话,可以在User验证器中添加验证规则如下:

<?php
namespace app\index\validate;
use think\Validate;
class User extends Validate{    // 验证规则
    protected $rule = [
        ['nickname', 'require|min:5', '昵称必须|昵称不能短于5个字符'],
        ['email', 'checkMail:thinkphp.cn', '邮箱格式错误'],
        ['birthday', 'dateFormat:Y-m-d', '生日格式错误'],
    ];    // 验证邮箱格式 是否符合指定的域名
    protected function checkMail($value, $rule)
    {        return 1 === preg_match('/^\w+([-+.]\w+)*@' . $rule . '$/', $value);
    }
}

自定义验证规则也支持返回动态的错误信息,只需要在验证方法里面返回错误信息字符串即可,例如:

<?php
namespace app\index\validate;
use think\Validate;
class User extends Validate{    // 验证规则
    protected $rule = [
        ['nickname', 'require|min:5', '昵称必须|昵称不能短于5个字符'],
        ['email', 'checkMail:thinkphp.cn', '邮箱格式错误'],
        ['birthday', 'dateFormat:Y-m-d', '生日格式错误'],
    ];    // 验证邮箱格式 是否符合指定的域名
    protected function checkMail($value, $rule)
    {        $result = preg_match('/^\w+([-+.]\w+)*@' . $rule . '$/', $value);        if (!$result) {            return '邮箱只能是' . $rule . '域名';
        } else {            return true;
        }
    }
}

如果输入了一个不是thinkphp.cn域名的邮箱地址,会提示如下错误信息:

邮箱只能是thinkphp.cn域名

控制器验证

前面我们讲了在模型中使用验证器进行数据验证的方法,下面来讲下如何在控制器中进行数据验证。

验证器类的定义不变,现在修改下控制器类:

namespace app\index\controller;
use app\index\model\User as UserModel;
use think\Controller;
class User extends Controller{    // 创建用户数据页面
    public function create()
    {        return view();
    }    public function add()
    {        $data = input('post.');        // 数据验证
        $result = $this->validate($data,'User');        if (true !== $result) {            return $result;
        }        $user = new UserModel;        // 数据保存
        $user->save($data);        return '用户[ ' . $user->nickname . ':' . $user->id . ' ]新增成功';
    }
}

然后访问

http://tp5.com/user/create

当输入一个错误的邮箱格式后提交

页面提示错误信息为:

email格式不符

如果有一些个别的验证没有在验证器里面定义,也可以使用静态方法单独处理,例如下面对birthday字段单独验证是否是一个有效的日期格式:

namespace app\index\controller;
use app\index\model\User as UserModel;
use think\Controller;
use think\Validate;
class User extends Controller{    // 创建用户数据页面
    public function create()
    {        return view();
    }    public function add()
    {        $data  = input('post.');        // 验证birthday是否有效的日期
        $check = Validate::is($data['birthday'],'date');        if (false === $check) {            return 'birthday日期格式非法';
        }        $user  = new UserModel;        // 数据保存
        $user->save($data);        return '用户[ ' . $user->nickname . ':' . $user->id . ' ]新增成功';
    }
}



回复列表



回复操作

正在加载验证码......

请先拖动验证码到相应位置