3.7 记录过滤器

过滤器提供了对模型记录属性审查和验证的途径。模型系统使用独立的Solar_Filter作为它的过滤器。(点击链接查看可用的过滤器类列表)

模型会基于数据库字段的定义自动地加一些的过滤器,当然你也可以加你自己的过滤器。当你使用save()方法保存一个记录对象时,这些过滤器将依次生效(自动过滤器最后生效)。如何有一个验证失败,那么save()方法也会失败。

[Note]过滤、审查和验证

可能在其他框架中这些术语有不同的意思。在Solar中,过滤是审查和/或验证数据的统一术语。“审查”是指根据需要更改数据,以使其符合特定的格式或准则。“验证”是指检查数据是否符合特定的规则或准则,但不更改数据。你可以根据需要以任何顺序对任何数据使用它们。

3.7.1 自动过滤器

这些过滤器是自动对下面这些类型的字段加载的。

Table 3.1. Solar模型的自动过滤器

字段信息自动过滤器
boolean validateBoolsanitizeBool
charvarchar validateString、验证字段宽的validateMaxLengthsanitizeString
smallintintbigint validateInt、验证整数类型最大值和最小值的validateRangesanitizeInt
numeric(定点十进制数) validateNumeric、验证定义的字段大小和范围的validateSizeScopesanitizeNumeric
float (浮点或双精度浮点) validateFloatsanitizeFloat
clob
date validateIsoDatesanitizeIsoDate
timevalidateIsoTimesanitizeIsoTime
timestamp(时期时间) validateIsoTimestampsanitizeIsoTimestamp

[Note]NOT NULL类型字段的自动过滤器是什么?

由于Solar_Filter的工作原理,在过滤行为实际发生之前,指定的数据字段并没有被定义为“required”。这是因为如果某字段为空,就不存在过滤行为了,因为根本没数据过滤。如果NOT NULL字段存在并为空(译者注:原文为不为空,我觉得不妥),它们就会被检查,但这是作为编程过滤逻辑的一部分,而不是作为一个单独的过滤器。你仍然可以添加validateNotBlank,以确保当NOT NULL字段出现时其不为空。

3.7.2 添加过滤器

要给模型添加一个或多个过滤器,就要编辑模型文件的_setup()方法并且调用$this->_addFilter()方法,此方法接受参数:对象属性名、过滤器名等参数。

<?php
class Vendor_Model_Foo extends Vendor_Sql_Model
{
    public function _setup()
    {
        // validate that a username is only alphanumeric characters
        $this->_addFilter('user_handle', 'validateAlnum');
        
        // validate column 'user_email' is not blank, and is an email address
        $this->_addFilter('user_email', 'validateNotBlank');
        $this->_addFilter('user_email', 'validateEmail');
        
        // validate column 'foo' is at least 8 characters long,
        // and has at least one non-alphanumeric character
        $this->_addFilter('foo', 'validateMinLength', 8);
        $this->_addFilter('foo', 'validatePregMatch', '/[^a-zA-Z0-9]/');
        
        // make sure the column 'bar' is one of a list of approved values
        $this->_addFilter('foo', 'validateInList', array(
            'baz', 'dib', 'zim', 'gir',
        ));
    }
}

现在,当你使用save()方法从模型保存记录时,在插入或更新数据库之前,这些过滤器将依次生效。如果有一个验证失败,save()方法也将失败。