模型

MixPHP 的模型内集成了基于场景功能非常强大的验证器,助你快速撸出安全规范的代码,该验证器参考了 Yii2,并且做了许多简化与扩充,如果你使用过 Yii2,那么你很快就能掌握。

模型主要有以下功能:

  • 数据验证
  • 数据库操作

| 类 |
| --- |
| mix\base\Model |

一个模型类的例子

<?php

namespace web\model;

use mix\base\Model;

class UserModel extends Model
{

    // 规则
    public function rules()
    {
        return [
        	['uid', 'integer', 'unsigned' => true, 'minLength' => 1, 'maxLength' => 10],
            ['message', 'string', 'minLength' => 3, 'maxLength' => 300, 'filter' => ['trim', 'strip_tags', 'htmlspecialchars']],
        ];
    }

    // 场景
    public function scenarios()
    {
        return [
        	'save' => ['required' => ['uid'], 'optional' => ['message']],
            'test' => ['required' => ['uid']],
        ];
    }

    // 属性消息
    public function attributeMessages()
    {
        return [
        	'uid' => '用户ID只能为无符号整数.',
            'message' => '消息长度只能为3~300.',
        ];
    }

    // 属性标签
    public function attributeLabels()
    {
        return [
        	'uid' => '用户ID',
            'message' => '消息',
        ];
    }
    
    // 保存
    public function save()
    {
    	$data = [
        	'uid' => $this->uid,
            'message' => $this->message,
        ];
        \Mix::app()->rdb->insert('post', $data)->execute();
    }

}

控制器内使用模型的例子

<?php

namespace web\controller;

use mix\web\Controller;

class UserController extends Controller
{

    public function actionIndex()
    {
        $model = new \web\model\UserModel();
        $model->attributes = \Mix::app()->request->get() + \Mix::app()->request->post();
        $model->setScenario('save');
        if (!$model->validate()) {
            return ['code' => 1, 'message' => '参数格式效验失败', 'data' => $model->errors];
        }
        $model->save()
        return ['code' => 0, 'message' => 'OK'];
    }

}

数据验证

MixPHP 的几乎可以验证所有类型的数据,数据验证是模型非常重要的功能,一个优秀的程序员不应该信任用户传过来的任何数据,为了安全性都应该做数据验证。

相关属性:

  • attributes
  • errors

相关方法:

  • setScenario
  • validate

需要重写的方法:

  • rules
  • scenarios
  • attributeLabels (可选)
  • attributeMessages (可选)

验证流程

结合上面的例子来理解流程。

  1. 将用户数据 $_GET $_POST 传入 attributes 属性。
  2. 调用 setScenario 设定当前需要验证的场景。
  3. 调用 validate 进行验证。
  4. 验证失败:展现 errors 属性内的错误信息。
  5. 验证成功:将场景内验证通过的字段在模型内生成对应的属性 (框架自动完成)。
  6. 验证成功:执行数据库操作。

验证规则 rules 方法

rules 方法内规则数组格式如下:

['字段名', '验证类型', '验证方法1' => 方法配置1, '验证方法2' => 方法配置2]

所有验证类型与对应可使用的规则如下:

return [
    ['字段名', 'integer', 'unsigned' => true, 'min' => 1, 'max' => 1000000, 'length' => 10, 'minLength' => 3, 'maxLength' => 5],
    ['字段名', 'double', 'unsigned' => true, 'min' => 1, 'max' => 1000000, 'length' => 10, 'minLength' => 3, 'maxLength' => 5],
    ['字段名', 'alpha', 'length' => 10, 'minLength' => 3, 'maxLength' => 5],
    ['字段名', 'alphaNumeric', 'length' => 10, 'minLength' => 3, 'maxLength' => 5],
    ['字段名', 'string', 'length' => 10, 'minLength' => 3, 'maxLength' => 5, 'filter' => ['trim', 'strip_tags', 'htmlspecialchars']],
    ['字段名', 'email', 'length' => 10, 'minLength' => 3, 'maxLength' => 5],
    ['字段名', 'phone'],
    ['字段名', 'url', 'length' => 10, 'minLength' => 3, 'maxLength' => 5],
    ['字段名', 'in', 'range' => ['A', 'B']],
    ['字段名', 'date', 'format' => 'Y-m-d'],
    ['字段名', 'compare', 'compareAttribute' => '另一个字段名'],
    ['字段名', 'match', 'pattern' => '/^[\w]{1,30}$/'],
    ['字段名', 'call', 'callback' => [$this, '方法名称']],
    ['字段名', 'file', 'mimes' => ['audio/mp3', 'video/mp4'], 'maxSize' => 1024 * 1],
    ['字段名', 'image', 'mimes' => ['image/gif', 'image/jpeg', 'image/png'], 'maxSize' => 1024 * 1],
];

大部分都可根据词意看出来如何使用,几个特殊的单独说一下:

  • compare:使用在修改密码的需求,判断新密码与重复密码两个字段的值是否一至。
  • call:使用在需要操作数据库的验证,在callback指定方法内操作数据库,方法需返回boolean,true通过验证,false返回错误。
  • file/image:mimes输入你想要限制的文件mime类型,MIME参考手册,验证成功后对应模型会增加一个字段名命名的属性,该属性为 UploadFile 类的实例化对象,在模型内可直接 $this->attribute->saveAs($filename) 另存为你需要存放的位置,更多方法请查看 "文件上传" 章节。

模型分层

MixPHP 模型功能强大,所以会成为 "胖模型",因此好的做法应该是将模型分层处理,比如这样分层:

  • 表单模型:一个控制配套一个表单模型,操作数据时调用数据模型。
  • 数据模型:一个数据库表配套一个数据模型,通过数据库组件操作数据库。

数据库操作

数据库操作请阅读 “同步/异步/协程客户端”章节。