ZendFramework2学习笔记 表单过滤、表单验证

ZF2有很多内建的Filter和Validator组件,可以方便地对表单数据进行处理。

Filter的作用是过滤表单数据,例如,去除一些空格,替换一些敏感词等。

Validator的作用是检验表单数据是否合规,如果不合规,则提供不合规原因的文本消息。

假设有这样一个Form:

表单数据存储到数据库之前的要求是:

用户名:过滤左右空格,字符都转换为小写,只能是由数字和字母字符组成,长度限制,数据库必须不存在该用户名。

密码:密码1和密码2必须相同,长度限制。

邮箱:必须符合密码格式,加密存储,长度限制。

手机:必须是11位数字字符组成,加密存储。

内容:将敏感词”SB“替换为”**“,内容尾部添加字符串”------Hello World !“。

首先,Form的构造函数添加基本的html标签元素:

class TestForm extends Form  implements InputFilterProviderInterface{

    protected $adapter;
    protected $inputFilter; 

    public function __construct($adap) {

        parent::__construct('test');

        $this->adapter = $adap;//由于该检验“数据库必须不存在该用户名”会用到“Zend\Validator\Db\RecordExists”,该validator需要数据库adpater初始化,因此,构造函数必须接收一个adapter参数

        $this->add(array(
            'name' => 'userName',
            'type' => 'Text',
            'options' => array(
                'label' => '用户名:',
            ),
            'attributes' => array(
                'size' => 60,
                'maxlength' => 100,
            ),
        ));
        $this->add(array(
            'name' => 'password1',
            'type' => 'Password',
            'options' => array(
                'label' => '密码:',
            ),
            'attributes' => array(
                'size' => 60,
                'maxlength' => 100,
            ),
        ));
        $this->add(array(
            'name' => 'password2',
            'type' => 'Password',
            'options' => array(
                'label' => '再次输入密码:',
            ),
            'attributes' => array(
                'size' => 60,
                'maxlength' => 100,
            ),
        ));
        $this->add(array(
            'name' => 'email',
            'type' => 'Text',
            'options' => array(
                'label' => '邮箱:',
            ),
            'attributes' => array(
                'size' => 60,
                'maxlength' => 100,
            ),
        ));
        $this->add(array(
            'name' => 'mobile',
            'type' => 'Text',
            'options' => array(
                'label' => '手机:',
            ),
            'attributes' => array(
                'size' => 60,
                'maxlength' => 100,
            ),
        ));
        $this->add(array(
            'name' => 'ifenc',
            'type' => 'Radio',
            'options' => array(
                'label' => '是否加密:',
                'value_options' => array(
                    'yes' => '是',
                    'no' => '否',
                )
            ),
        ));
        $this->add(array(
            'name' => 'content',
            'type' => 'Textarea',
            'options' => array(
                'label' => '内容:',
            ),
            'attributes' => array(
                'cols' => 80,
                'rows' => 6,
            ),
        ));
        $this->add(new Csrf('security'));//这个element阻止跨站点伪造请求攻击
        $this->add(array(
            'name' => 'send',
            'type' => 'Submit',
            'attributes' => array(
                'value' => '确定',
            ),
        ));
    }
}

然后为该Form的各个元素添加filter和validator:

class TestForm extends Form  implements InputFilterProviderInterface{

    public function getInputFilterSpecification() {
        return array(
            'userName' => array(
                'required' => true,
                'filters'  => array(
                    array('name' => 'StringTrim'),//去除前后空格
                    array('name' => 'StringToLower'),//转为小写字符
                ),
                'validators' => array(
                    array('name' => 'NotEmpty'),//不允许为空
                    array('name' => 'Alnum'),//注意,Zend\I18n\Validator\Alnum要求打开intl的php扩展,具体做法是,打开php.ini文件,将“extension=php_intl.dll”前面的“;”删除,然后重启web服务即可。
                    array(
                        'name'    => 'StringLength',//限制长度
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 3,
                            'max'      => 256,
                        ),
                    ),
                    array(
                        'name'    => 'Db\NoRecordExists',//不允许数据库已存在该用户名,说明,数据库中有表user,user表有字段name就是存储的用户名,因此,该validator就是检验user表的name字段
                        'options' => array(
                            'table' => 'user',
                            'field' => 'name',
                            'adapter' => $this->adapter,
                        ),
                    ),
                ),
            ),
            'password1' => array(
                'required' => true,
                'validators' => array(
                    array(
                        'name'    => 'StringLength',//限制长度
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 6,
                            'max'      => 6,
                        ),
                    ),
                ),
            ),
            'password2' => array(
                'required' => true,
                'validators' => array(
                    array(
                        'name'    => 'StringLength',//限制长度
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 6,
                            'max'      => 6,
                        ),
                    ),
                    array(
                        'name'    => 'Identical',//检验是否和password1相同,Zend\Validator\Identical可以用于检验另一个元素和自己是否相同
                        'options' => array(
                            'token' => 'password1',
                        ),
                    ),
                ),
            ),
            'email' => array(
                'required' => true,
                'validators' => array(
                    array(
                        'name'    => 'StringLength',//限制长度
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 3,
                            'max'      => 256,
                        ),
                    ),
                    array('name'    => 'EmailAddress'),//检验邮箱格式,Zend\Validator\Identical\EmailAddress专门用于检验邮箱格式
                ),
            ),
            'mobile' => array(
                'required' => true,
                'validators' => array(
                    array(
                        'name'    => 'StringLength',//限制长度
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 11,
                            'max'      => 11,
                        ),
                    ),
                    array('name'    => 'Digits')//必须为数字字符
                ),
            ),
            'ifenc' => array(
                'required' => true,

            ),
            'content' => array(
                'required' => true,
                'filters'  => array(
                    array(
                        'name'    => 'PregReplace',//替换敏感词
                        'options' => array(
                            'pattern' => '/SB/',
                            'replacement' => '**'
                        ),
                    ),
                    array(
                        'name'    => '\Zend\Filter\Callback',//加尾巴的自定义filter回调
                        'options' => array(
                            'callback' => array('Test\Form\MyAddTailFilter', 'addTail')//MyAddTailFilter是自定义的一个filter回调
                        ),
                    ),
                ),
                'validators' => array(
                    array('name' => 'NotEmpty'),//不允许为空
                    array(
                        'name'    => 'StringLength',//限制长度
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min'      => 1,
                            'max'      => 1024,
                        ),
                    ),
                ),
            ),
        );
    }
}

其中,为content添加尾巴的filter回调类MyAddTailFilter代码如下:

namespace Test\Form;

class MyAddTailFilter {
    public function addTail($param){
        $ret = $param."----hello world !";
        return $ret;
    }
}

控制器:

use Zend\Filter\Encrypt;
use Zend\Filter\Decrypt;
use Test\Form\TestForm;
use Test\Form\MyValidatorTranslator;

class TestController extends AbstractActionController {

    public function testformAction() {

        $form = new TestForm($this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'));//为检验是否用户名已存在的validator提供数据库adapter
        $request = $this->getRequest();
        if ($request->isPost()) {
            $form->setData($request->getPost());
            if ($form->isValid()) {
                $filteredValues = $form->getInputFilter()->getValues();//检验成功后,获取过滤后的数据

		//将email和手机号码加密
                $encKey = '123456';
                $enc = new Encrypt(array('adapter' => 'BlockCipher'));//创建加密filter
                $enc->setKey($encKey);//设置key
                $enc->setVector('12345678901234567890');//加盐
                //加密email
                $filteredValues['email'] = $enc->filter($filteredValues['email']);
		//加密手机号
                $filteredValues['mobile'] = $enc->filter($filteredValues['mobile']);

		//解密
                //$dec = new Decrypt(array('adapter' => 'BlockCipher'));
                //$dec->setKey($encKey);//设置key
                //$filteredValues['email'] = $dec->filter($filteredValues['email']);
                //$filteredValues['mobile'] = $dec->filter($filteredValues['mobile']);

		//将$filteredValues保存到数据库
		//......
            }
        }

        return array(
            'tform' => $form,
        );
     }
}

testform.phtml

$this->tform->setAttribute('action', $this->url('test', array('action' => 'testform')));
$this->tform->setAttribute('method', 'POST');
$this->tform->prepare();

echo "<div class='tf'>";
echo '<div>'.$this->form()->openTag($this->tform).'</div>';
//$um = $this->tform->get('userName');
//echo '<div>'.$this->formLabel($um).$this->formText($um).$this->formElementErrors($um).'</div>';
echo '<div>'.$this->formRow($this->tform->get('userName')).'</div>';
echo '<div>'.$this->formRow($this->tform->get('password1')).'</div>';
echo '<div>'.$this->formRow($this->tform->get('password2')).'</div>';
echo '<div>'.$this->formRow($this->tform->get('email')).'</div>';
echo '<div>'.$this->formRow($this->tform->get('mobile')).'</div>';
$yn = $this->tform->get('ifenc');
echo "<div>".$this->formLabel($yn).$this->formRadio($yn).$this->formElementErrors($yn).'</div>';//对Radio标签,直接用$this->formRow显示的效果很难看,因此,先formLabel,在formRadio,最后显示检验失败原因的消息formElementErrors
//echo '<div>'.$this->formRow($this->tform->get('ifenc')).'</div>';
echo '<div>'.$this->formRow($this->tform->get('content')).'</div>';
echo '<div>'.$this->formHidden($this->tform->get('security')).'</div>';
echo '<div>'.$this->formRow($this->tform->get('send')).'</div>';
echo '<div>'.$this->form()->closeTag().'</div>';
echo "</div>";

至此,已经完成了将表单保存到数据库之前的,对表单数据进行过滤和检验的工作!

以下是zf2中的一些标准filter和validator:

zf2的一些标准filter类:

Zend\Filter\StringToLower:字符串转小写。

Zend\Filter\StringToUpper:字符串转大写。

Zend\Filter\StringTrim:过滤掉字符串前后“空白字符”和指定字符。

Zend\Filter\StripNewlines:过滤掉字符串中的\r\n等新行符。

Zend\Filter\StripTags:过滤掉字符串中的xml和html标签,接受不过滤的标签和标签属性参数。

Zend\Filter\Word\CamelCaseToUnderscore:首字符大写分隔字符串转“_”分隔字符串。

Zend\Filter\Word\UnderscoreToCamelCase:“_”分隔字符串转首字符大写分隔字符串。

Zend\Filter\Word\UnderscoreToSeparator:“_”分隔字符串转“ ”或指定分隔符分隔字符串。

Zend\Filter\Word\UnderscoreToDash:“_”分隔字符串转“-”分隔字符串。

Zend\Filter\Word\CamelCaseToDash:首字符大写分隔字符串转“-”分隔字符串。

Zend\Filter\Word\DashToCamelCase:“-”分隔字符串转首字符大写分隔字符串。

Zend\Filter\Word\DashToSeparator:“-”分隔字符串转“ ”或者指定分隔符分隔字符串。

Zend\Filter\Word\DashToUnderscore:“-”分隔字符串转“_”分隔字符串。

Zend\Filter\Word\CamelCaseToSeparator:首字符大写分隔字符串转“ ”或者指定分隔符分隔字符串。

Zend\Filter\Word\SeparatorToCamelCase:“ ”或者指定分隔符分隔字符串转首字符大写分隔字符串。

Zend\Filter\Word\SeparatorToDash:“ ”或者指定分隔符分隔字符串转“-”分隔字符串。

Zend\Filter\Word\SeparatorToSeparator:“ ”或者指定分隔符分隔字符串转“-”或指定分隔符分隔字符串。

Zend\Filter\HtmlEntities:转换字符串中的‘&‘、‘"‘、“<”等特殊字符。

Zend\I18n\Filter\Alnum:过滤字符串中非字母字符和数字字符,可选保留空格。

Zend\I18n\Filter\Alpha:过滤字符串中非字母字符,可选保留空格。

Zend\Filter\Digits:过滤字符串中非数字字符。

Zend\Filter\Boolean:将"yes","no","true","false","1","0",1,0等字符串或者数字转为布尔值true,false。

Zend\Filter\Int:字符串转整数,例如“-5 abcded”,过滤后为-5。

Zend\Filter\Null:如果empty(字符串)是true,则过滤后为NULL。

Zend\I18n\Filter\NumberFormat:格式化数字,例如$filter = new NumberFormat("en_US", NumberFormatter::PERCENT);$filter->filter(0.80);返回“80%”。

Zend\Filter\PregReplace:使用正则表达式查找字符串并用给定字符串替换。

Zend\Filter\Callback:让filter回调开发者自定义函数(可以是类的成员函数或者php53以上版本的魔术方法__invoke)过滤input。

Zend\Filter\BaseName:对文件路径字符串过滤掉文件夹字符串,返回文件名,例如“/etc/t.t”和“c:\t\t.t”返回“t.t”。

Zend\Filter\Dir:对文件路径字符串过滤掉文件名,返回文件夹字符串,例如“/etc/t.t”和“c:\t\t.t”返回“/etc”和“c:\t”。

Zend\Filter\RealPath:返回真实目录,目录要存在,接收是否创建目录的参数,例如“/etc/a/b/c/../../../”,过滤后返回“/etc”。

Zend\Filter\UriNormalize:完善uri,例如$filter = new UriNormalize(array(‘enforcedScheme‘ => ‘https‘));$filter->filter(‘www.z.cn‘);返回“https://www.z.cn”。

Zend\Filter\File\Rename:重命名或者移动文件。

Zend\Filter\File\RenameUpload:重命名或者移动上传文件到一个新目录。可以设置文件名为随机名称、原名或指定名,是否保留扩展名。建议任何时候都不要使用原名。

Zend\Filter\Compress:压缩字符串、文件或目录,支持的格式有bz2、gz、lzf、rar、tar、zip。注意,lzf只支持字符串压缩,rar、tar只支持文件和目录压缩。

Zend\Filter\Decompress:解压缩字符串、文件或目录,支持的格式同Zend\Filter\Compress。

Zend\Filter\Encrypt:加密字符串(有“BlockCipher”和“OpenSSL”2个adapter可选,BlockCipher使用的是Mcrypt扩展)。

Zend\Filter\Decrypt:解密字符串。

Zend\Filter\Inflector:可用于过滤、格式化分割的字符串,可为分割字符串不同部分设置不同的filters。

zf2的一些标准validator类:

Zend\Validator\StringLength:限制字符串长度范围,可选编码方式。

Zend\I18n\Validator\Alnum:检验字符串是否由字母字符和数字字符组成,可选允许空格。

Zend\I18n\Validator\Alpha:检验字符串是否由字母字符组成,可选允许空格。

Zend\Validator\Hex:检验字符串是否是16进制字符(‘0’~‘9’、‘A~‘F’)组成。

Zend\Validator\Digits:检验输入是否是数字(包括数值型输入)。

Zend\I18n\Validator\Int:检验整数。

Zend\I18n\Validator\Float:检验输入是否包含一个浮点数。

Zend\Validator\Between:检查数字是否在给定范围内,可选包括边界值。

Zend\Validator\LessThan:检查数字是否大小于给定值,可选等于给定值。

Zend\Validator\GreaterThan:检查数字是否大于给定值,可选等于给定值。

Zend\Validator\NotEmpty:检验输入是否非空。

Zend\Validator\EmailAddress:检验输入是否是有效email地址。

Zend\Validator\Regex:检验字符串是否和指定正则表达式匹配。

Zend\Validator\Identical:检查输入是否和给定项相同。

Zend\Validator\Callback:让validator回调开发者自定义函数(可以是类的成员函数或者php53以上版本的魔术方法__invoke)检验input。

Zend\Validator\Date:检验输入是否包含一个日期,默认格式yyyy-MM-dd,也可自定义格式。

Zend\Validator\Db\RecordExists:检查输入是否在数据库某个表某个字段存在。

Zend\Validator\Db\NoRecordExists:检查输入是否在数据库某个表某个字段不存在,可用于检查用户名是否已注册等。

Zend\Validator\InArray:检验输入是否包含在数组中。

Zend\Validator\Hostname:检验DNS域名、ip地址、localhost。

Zend\Validator\Ip:检验输入是否是ip地址,支持ipv4、ipv6。

Zend\Validator\Isbn:检验输入是否是一个ISBN-10或者ISBN-13的值。

Zend\Validator\Barcode:检验字符串是不是条码值。

Zend\Validator\Iban:检查字符串是否是国际银行编号。

Zend\I18n\Validator\PostCode:检验输入是否是邮编。

Zend\Validator\CreditCard:检验输入是否可能是一个信用卡号码,可设置信用卡发行单位的网络api检验。

Zend\Validator\Sitemap\xxx:sitemap xml 协议相关检验。

Zend\Validator\Step:检验数字值是否是基于baseValue和step所产生的值。

文件validator类:

Zend\Validator\File\Hash:检验文件的哈希值是否和提供的哈希值和算法匹配。

Zend\Validator\File\Crc32:检验文件的哈希值是否和提供的crc32哈希值匹配。

Zend\Validator\File\Md5:检验文件的哈希值是否和提供的md5哈希值匹配。

Zend\Validator\File\Sha1:检验文件的哈希值是否和提供的sha1哈希值匹配。

Zend\Validator\File\Extension:检验文件的扩展名。

Zend\Validator\File\ExcludeExtension:检验排除指定的文件扩展名。

Zend\Validator\File\MimeType:检验文件的MIME类型。

Zend\Validator\File\ExcludeMimeType:检验排除指定的文件MIME类型。

Zend\Validator\File\Exists:检验文件是否在指定的某个目录中存在。

Zend\Validator\File\NotExists:检验文件是否在指定的所有目录中都不存在。

Zend\Validator\File\IsCompressed:检验文件是否是一个压缩文件(zip、gzip等),根据MIME类型检验。

Zend\Validator\File\Size:检验文件的大小是否在指定范围内。

Zend\Validator\File\ImageSize:检验图像文件宽高是否在指定范围内。

Zend\Validator\File\IsImage:检验文件是否是图像文件(jpg、png等),根据MIME类型检验。

Zend\Validator\File\UploadFile:检验是否一个文件通过POST表单被上传了,并在发生上传错误的时候返回描述消息。

Zend\Validator\File\WordCount:检验文件内的单词数目是否在指定范围内。



时间: 2024-10-14 16:59:04

ZendFramework2学习笔记 表单过滤、表单验证的相关文章

HTML5学习笔记(二)——表单1

表单一直是网页必不可少的一部分,一直以来,表单的作用被无限扩展,发展出了诸多新奇的用法,老版的HTML只支持很少的一部分常用表单,许多的新表单都需要借助CSS与JavaScript语言来进行构建,现在HTML5来了,她带来了新的表单,这些强大的表单项,可以省去一大块复杂的JavaScript代码,很值得去学习. 而且在新的表单里面,不再像以前每个表单都必须位于<form></form>之内,只要在<form></form>内定义一个id,然后在网页任何位置都

Bootstrap快速学习笔记(2)表单系列之二

欢迎收看大奥编写的Bootstrap快速学习笔记(2)表单系列之二 本学习笔记根据[慕课网]教程修改而来,用它学习Bootstrap,将会带来全新的体验哦: 表单控件大小 表单控件状态 按钮 图像 详细介绍 表单控件大小表单控件大小可以通过给表单控件添加class类来实现,如果想要比较大,则添加input-lg类,如果想要比较小, 则添加input-sm类,但这仅是对高度进行了处理,如果要对宽度进行处理,需要在每个input控件外围添加div容器并带有col-xs-4类,并 且要在这组控件的外围

Django学习笔记(五)—— 表单

疯狂的暑假学习之  Django学习笔记(五)-- 表单 参考:<The Django Book> 第7章 1. HttpRequest对象的信息 request.path                                 除域名以外的请求路径,斜杠开头                      "/hello/" request.get_host()                      主机名                              

Bootstrap快速学习笔记(2)表单系列之一

欢迎收看大奥编写的Bootstrap快速学习笔记(2)表单系列之一 本学习笔记根据[慕课网]教程修改而来,用它学习Bootstrap,将会带来全新的体验哦: .form-control类 水平表单 内联表单 详细介绍 form-control类把该类直接添加到控件上: 1.宽度变成了100%:2.设置了一个浅灰色(#ccc)的边框:3.具有4px的圆角:4.设置阴影效果,并且元素得到焦点之时,阴影和边框效果会有所变化:5.设置了placeholder的颜色为#999 水平表单最外层form标签要

html+css学习笔记 5[表格、表单]

表格 -- 默认样式重置 表格标签:     table 表格     thead 表格头     tbody 表格主体     tfoot 表格尾     tr 表格行     th 元素定义表头     td 元素定义表格单元 表格样式重置 table{border-collapse:collapse;} 单元格间隙合并 th,td{padding:0;}重置单元格默认填充   单元格合并 rowspan  属性规定单元格可横跨的行数.     <td rowspan="2"

bootstrap学习笔记一 登录水平表单

先上效果图: 样式定义: <form class="form-horizontal"> <div class="control-group"> <label class="control-label" for="UserName">用户名</label> <div class="controls"> <input type="tex

MySQL学习笔记-数据类型与操作数据表

MySQL学习笔记-数据类型与操作数据表 数据类型:  1.字符型  2.整型  3.浮点型  4.日期时间型 数据表操作:  1.插入记录  2.查找记录 记录操作:  1.创建数据表  2.约束的使用 1.数据类型 [1]整型: 数据类型 存储范围 字节 TINYINT 有符号型:-128~127(-2^7~2^7 -1),无符号型0~255(0~2^8 -1) 1 SMALLINT 有符号型:-2^15~2^15 -1,无符号型0~2^16 -1 2 MEDIUMINT 有符号型:-2^2

sqlite学习笔记6:更新表数据

一 条件判断 在SQL中条件判断使用where,相当于其他变成语言中的if,基本用法如: SELECT column1, column2, columnN FROM table_name WHERE [condition] 另外,SQL支持数学运算,逻辑运算,位于运算等等,均可放在WHERE子句中. 二 更新表 基本语法如下: UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE

MySQL学习笔记之五 有关数据表操作

MySQL在创建表的时候,创建一个.frm文件保存表和列定义.索引存储在一个有.MYI(MYindex)扩展名的文件并且数据存储在有.MYD(MYData)扩展名的文件中.   一.用SHOW/ DESCRIBE语句显示数据表的信息 语法: SHOW TABLES [FROM db_name] [LIKE wild] or SHOW COLUMNS FROM tbl_name [FROM db_name] [LIKE wild] or SHOW INDEX FROM tbl_name [FROM