跳转到内容

模型验证


概览

Phalcon\Mvc\Model提供了多个事件来验证数据并实现业务规则。

<?php

namespace MyApp\Models;

use Phalcon\Mvc\Model;
use Phalcon\Filter\Validation;
use Phalcon\Filter\Validation\Validator\Uniqueness;

class Customers extends Model
{
    public function validation()
    {
        $validator = new Validation();

        $validator->add(
            'cst_email',
            new Uniqueness(
                [
                    'message' => 'The customer email must be unique',
                ]
            )
        );

        return $this->validate($validator);
    }
}

数据完整性

数据完整性在每个应用程序中都至关重要。你可以在模型中实现验证器,引入另一层验证,以确保存储到数据库中的数据符合你的业务规则。

特殊的validation事件允许我们在记录上调用内置验证器。Phalcon 在此验证阶段暴露了额外的内置验证器。所有可用的验证器都在Phalcon\Validation命名空间下。

<?php

namespace MyApp\Models;

use Phalcon\Mvc\Model;
use Phalcon\Filter\Validation;
use Phalcon\Filter\Validation\Validator\Uniqueness;
use Phalcon\Filter\Validation\Validator\InclusionIn;

class Invoices extends Model
{
    public function validation()
    {
        $validator = new Validation();

        $validator->add(
            'inv_status_flag',
            new InclusionIn(
                [
                    'domain'  => [
                        'Paid',
                        'Unpaid',
                    ],
                    'message' => 'The invoice must be ' .
                                 'either paid or unpaid',
                ]
            )
        );

        $validator->add(
            'inv_number',
            new Uniqueness(
                [
                    'message' => 'The invoice number must be unique',
                ]
            )
        );

        return $this->validate($validator);
    }
}

上述示例使用内置验证器Phalcon\Filter\Validation\Validator\InclusionIn进行验证。它检查字段inv_status_flag的值是否在一个域名列表中。如果该值未包含在此方法中,则验证器将失败并返回false.

注意

若要了解有关验证器的更多信息,请参阅验证文档

消息

Phalcon\Mvc\Model使用Phalcon\Messages\Messages集合来存储验证过程中生成的任何验证消息。

每条消息都是Phalcon\Messages\Message的实例,生成的消息集合可以通过getMessages()方法检索。每条消息提供了额外的信息,例如生成该消息的字段名称或消息类型:

<?php

if (false === $invoice->save()) {
    $messages = $invoice->getMessages();

    foreach ($messages as $message) {
        echo 'Message: ', $message->getMessage();
        echo 'Field: ', $message->getField();
        echo 'Type: ', $message->getType();
    }
}

Phalcon\Mvc\Model可以生成以下类型的验证消息:

类型 生成时
ConstraintViolation 字段是虚拟外键的一部分,尝试插入/更新一个在引用模型中不存在的值
InvalidCreateAttempt 尝试创建已经存在的记录
InvalidUpdateAttempt 尝试更新不存在的记录
InvalidValue 验证器因无效值而失败
PresenceOf 数据库中具有非null属性的字段尝试插入/更新一个null

The getMessages()方法可以在模型中被重写,以替换/翻译 ORM 自动生成的默认消息:

<?php

namespace MyApp\Models;

use Phalcon\Mvc\Model;

class Invoices extends Model
{
    public function getMessages()
    {
        $messages = [];

        foreach (parent::getMessages() as $message) {
            switch ($message->getType()) {
                case 'InvalidCreateAttempt':
                    $messages[] = 'The record cannot be created '
                                . 'because it already exists';
                    break;

                case 'InvalidUpdateAttempt':
                    $messages[] = "The record cannot be updated '
                                . 'because it doesn't exist";
                    break;

                case 'PresenceOf':
                    $messages[] = 'The field ' 
                                . $message->getField() 
                                . ' is mandatory';
                    break;
            }
        }

        return $messages;
    }
}

验证失败事件

当数据验证过程发现任何不一致时,会有其他可用事件:

操作 名称 解释
插入或更新 notSaved 触发当INSERTUPDATE操作由于任何原因失败时
插入、删除或更新 onValidationFails 触发当任何数据操作失败时

自定义

The 验证文档详细说明了如何创建自己的验证器。你可以使用这些验证器并在多个模型中复用它们。一个验证器也可以简单如:

<?php

namespace MyApp\Models;

use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Message;

class Invoices extends Model
{
    public function validation()
    {
        if ('Unpaid' === $this->inv_type_flag) {
            $message = new Message(
                'Unpaid invoices are not allowed',
                'inv_type_flag',
                'UnpaidInvoiceType'
            );

            $this->appendMessage($message);

            return false;
        }

        return true;
    }
}
无噪 Logo
无噪文档
25 年 6 月翻译
文档源↗