标签:zend_form_element 生成 生成表单元素 zend framework
表单由元素组成,它一般对应于 HTML 表单输入。Zend_Form_Element 封装了单个表单元素,并完成下列工作:
基础类 Zend_Form_Element 对许多类有合理的缺省设置,但最好还是继承这个类来完成特殊意图的元素。另外,Zend Framework 带有许多标准的 XHTML 元素。
Zend_Form_Element 利用 Zend_Loader_PluginLoader 来使开发者指定替代校验器、过滤器和装饰器的位置。每个都有它自己携带的插件加载器,并使用通用的访问器来读取或修改它们。
下列加载器类型和各种各样的插件加载器方法一起使用:‘validate‘、 ‘filter‘ 和 ‘decorator‘。类型名是大小写敏感的。
插件加载器交互使用的方法如下:
定制的校验器、过滤器和装饰器是在表单和封装定制功能之间共享功能的简单的办法。
插件的一个普通用例是来为标准类提供替换。例如,如果想实现一个不同的 ‘Label‘ 装饰器 -- 如总要追加冒号 --你可以创建你自己的带有类前缀的 ‘Label‘ 装饰器,然后把它加到你的前缀路径。
让我们从定制标签装饰器来开始,给它一个类前缀"My_Decorator",类文件就是 "My/Decorator/Label.php"。
<?php classMy_Decorator_Label extends Zend_Form_Decorator_Abstract { protected $_placement = 'PREPEND'; public function render($content) { if (null === ($element =$this->getElement())) { return $content; } if (!method_exists($element,'getLabel')) { return $content; } $label = $element->getLabel() . ':'; if (null === ($view =$element->getView())) { return$this->renderLabel($content, $label); } $label =$view->formLabel($element->getName(), $label); return $this->renderLabel($content,$label); } public function renderLabel($content,$label) { $placement = $this->getPlacement(); $separator = $this->getSeparator(); switch ($placement) { case 'APPEND': return $content . $separator .$label; case 'PREPEND': default: return $label . $separator .$content; } } }
现在,当元素寻找装饰器时,就使用这个插件路径:
$element->addPrefixPath('My_Decorator','My/Decorator/', 'decorator');
另外,我们可以在表单一级来做以确保所有的装饰器使用这个路径:
$form->addElementPrefixPath('My_Decorator','My/Decorator/', 'decorator');
用这个添加的路径,当添加一个装饰器,将首先搜索 ‘My/Decorator/‘ 路径来检查是否存在装饰器。结果,如果请求 ‘Label‘ 装饰器,‘My_Decorator_Label‘ 将被使用。
在校验之前对输入执行规范化常常是有用的并/或必需的 - 例如,你可能想要剥离所有 HTML,在剩下的东东上运行校验来确保提交有效。或者你可能想把输入的数据两边的空格都消掉,这样 StringLength 校验器就不会返回失败。这些操作使用 Zend_Filter 来执行,并且 Zend_Form_Element 对过滤链有支持,让你指定多个连续的过滤器来用。在校验期间和通过 getValue() 读取元素值的时候都会发生校验:
<?php $filtered =$element->getValue(); ?>
有两个办法添加过滤器:
看一些例子:
<?php // 具体的过滤器实例: $element->addFilter(newZend_Filter_Alnum()); // 合格的全类名: $element->addFilter('Zend_Filter_Alnum'); // 短过滤器名: $element->addFilter('Alnum'); $element->addFilter('alnum'); ?>
短名一般就是过滤器名去掉前缀,缺省就是去掉 ‘Zend_Filter_‘ 前缀。另外,首字母不需要大写。
使用定制的过滤器类 |
|
如果你有自己的一组过滤器,可以通过 addPrefixPath() 来告诉 Zend_Form_Element。例如,如果你在 ‘My_Filter‘ 前缀下有过滤器,这样来告诉 Zend_Form_Element: <?php $element->addPrefixPath('My_Filter', 'My/Filter/', 'filter'); ?> (回忆一下第三个参数用来指示哪个是执行这个动作的插件加载器) |
任何时候需要非过滤的数据,使用 getUnfilteredValue() 方法:
<?php $unfiltered =$element->getUnfilteredValue(); ?>
过滤器带有这些方法:
如果你赞同安全咒语“过滤输入,转义输出”,你将会校验(“过滤输入”)你的表单输入。在 Zend_Form 里,每个元素包含它自己的由 Zend_Validate_* 校验器组成的校验器链。
两个办法添加校验器到校验器链:
看一些例子:
<?php // Concrete validatorinstance: $element->addValidator(newZend_Validate_Alnum()); // Fully qualifiedclass name: $element->addValidator('Zend_Validate_Alnum'); // Short validatorname: $element->addValidator('Alnum'); $element->addValidator('alnum'); ?>
短名一般就是校验器名去掉前缀,缺省就是去掉 ‘Zend_Validate_‘ 前缀。另外,首字母不需要大写。
使用定制的校验器类 |
|
如果你有自己的一组校验器,可以通过 addPrefixPath() 来告诉 Zend_Form_Element。例如,如果你在 ‘My_Validator‘ 前缀下有校验器,这样来告诉 Zend_Form_Element: <?php $element->addPrefixPath(‘My_Validator‘, ‘My/Validator/‘, ‘validate‘); ?> (回忆一下第三个参数用来指示哪个是执行这个动作的插件加载器) |
如果特定的校验失败,为阻止后面的校验工作,传递第二个参数 true (布尔型):
<?php $element->addValidator('alnum',true); ?>
如果你使用一个字符串名来添加一个校验器,并且这个校验器接受参数给构造器,你可以把这个第三个参数addValidator() 作为数组传递:
<?php $element->addValidator('StringLength',false, array(6, 20)); ?>
这样传递参数应该按照它们在构造器里定义的顺序进行。上述例子将带参数$min 和 $max 实例化 Zend_Validate_StringLenth 类:
<?php $validator = newZend_Validate_StringLength(6, 20); ?>
提供定制的校验错误消息 |
|
有些开发者可能想为校验器提供定制的错误消息。 Zend_Form_Element::addValidator() 的 $options 参数让你通过提供 ‘messages‘ 键并把它设置为键/值对(用来设置消息模板)的数组来完成。你需要知道特定校验器的各种各样的校验错误类型的错误代码。 稍好的选择是在表单中使用 Zend_Translate_Adapter。错误代码通过缺省的错误装饰器自动传递给适配器,然后你可以通过为你的校验器的各种错误代码设置翻译来指定自己的错误消息字符串。 |
你也可以使用 addValidators() 一次性设置许多校验器。基本的用法是传递数组的数组,每个数组包含 1 到 3 个匹配 addValidator() 的构造器的值:(一般这个可能会用到的比较多。)
<?php $element->addValidators(array( array('NotEmpty', true), array('alnum'), array('stringLength', false, array(6, 20)), )); ?>
如果你想做的更明确和更详细,可以使用数组键 ‘validator‘、‘breakChainOnFailure‘ 和 ‘options‘:
<?php $element->addValidators(array( array( 'validator' => 'NotEmpty', 'breakChainOnFailure' => true), array('validator' => 'alnum'), array( 'validator' => 'stringLength', 'options' => array(6, 20)), )); ?>
这个用法展示如何在配置文件中配置校验器:
element.validators.notempty.validator= "NotEmpty" element.validators.notempty.breakChainOnFailure= true element.validators.alnum.validator= "Alnum" element.validators.strlen.validator= "StringLength" element.validators.strlen.options.min= 6 element.validators.strlen.options.max= 20
注意每个条目有一个键,不管是否需要,这是使用配置文件规定的 --但它也帮助清楚理解哪个参数用于什么。请记住任何校验器选项必需按顺序指定。
为校验一个元素,传递值给 isValid():
<?php if($element->isValid($value)) { // valid } else { // invalid } ?>
注:上面这些重点,经常会用到。
在过滤后的值上校验 |
|
Zend_Form_Element::isValid() 在校验之前通过提供过滤器链来过滤(输入)值。 |
|
校验上下文 |
|
Zend_Form_Element::isValid() 支持另外的参数 $context。当校验一个表单 Zend_Form::isValid() 传递由 $context 处理过的数据的整个数组,Zend_Form_Element::isValid() 接着把它传递给每个校验器。这意味着你可以写知道数据传递给其它表单元素的校验器,例如,标准的注册表单有密码和密码确认元素,得有一个校验它们是否匹配。这样的校验器看起来如下: <?php class My_Validate_PasswordConfirmation extends Zend_Validate_Abstract { const NOT_MATCH = 'notMatch'; protected $_messageTemplates = array( self::NOT_MATCH => 'Password confirmation does not match' ); public function isValid($value, $context = null) { $value = (string) $value; $this->_setValue($value); if (is_array($context)) { if (isset($context['password_confirm']) && ($value == $context['password_confirm'])) { return true; } } elseif (is_string($context) && ($value == $context)) { return true; } $this->_error(self::NOT_MATCH); return false; } } ?>
|
校验器按顺序处理,除非用 breakChainOnFailure 为 true 创建的校验器并且校验失败,否则每个校验器都要处理。确认按合理的顺序指定你的校验器。
校验失败后,你可以从校验器链读取错误代码和消息:
<?php $errors = $element->getErrors(); $messages =$element->getMessages(); ?>
(注意:错误消息返回的是一个有错误代码/错误消息对的联合数组)
除了校验器外,你可以用 setRequired(true) 指定必需的元素。缺省地,这个标志是 false,如果没有值传递给 isValid(),校验器链将被跳过。你也可以用许多办法来修改它的行为:
如果你不想这样,传递给 setAutoInsertNotEmptyValidator($flag) 一个 false 值使它关闭。这将防止 isValid() 在校验器链里放置一个 ‘NotEmpty‘ 校验器。
使用 Zend_Form_Elements 作为通用的校验器 |
|
Zend_Form_Element 实现 Zend_Validate_Interface,意味着元素可以在其它非表单相关的校验链里被用做校验器。 |
校验相关的方法包括:
有时,你想定制一条或多条特定的错误消息来替代由附加到元素上的校验器所带的错误消息。另外,有时候你想自己标记表单无效,从 1.6.0 版开始,通过下列方法来实现这个功能。
所有用这个方式设置的错误可以被翻译。
对许多 web 开发者来说一个特别的痛苦是 XHTML 表单自己的生成。对于每个元素,开发者需要为元素自己生成 markup,label 是一个典型,并且,如果他们对用户很好,需要为显示校验错误消息生成 markup。在页面元素越多,任务就越不琐碎。
Zend_Form_Element 试图用 "装饰器" 来解决这个问题。装饰器就是个类,可以访问元素和用于解析内容的方法。
Zend_Form_Element 所使用的缺省的装饰器是:
不需要加载缺省装饰器 |
|
缺省地,在对象初始化过程中加载缺省装饰器。你可以通过传递 ‘disableLoadDefaultDecorators‘ 选项给构造器来关闭它: <?php $element = new Zend_Form_Element('foo', array('disableLoadDefaultDecorators' => true)); 该选项可以和企图选项混合,它们都是数组选项或在 Zend_Config 对象里。 |
因为装饰器注册顺序的原因 --先注册先执行--你需要确保按合适的顺序来注册装饰器,或者确保以健全的方式设置替换选项。这个是注册缺省装饰器的例子:
<?php $this->addDecorators(array( array('ViewHelper'), array('Errors'), array('HtmlTag', array('tag' => 'dd')), array('Label', array('tag' => 'dt')), )); ?>
初始内容由 ‘ViewHelper‘ 装饰器生成,它生成表单元素自己。接着,‘Errors‘ 装饰器从元素里抓取错误消息。如果有任何错误,就传递给 ‘FormErrors‘ 视图助手来解析。下一个装饰器 ‘HtmlTag‘ 在一个 HTML <dd> 标签里封装元素和错误。最后,‘label‘ 装饰器读取元素的标签并传递给 ‘FormLabel‘ 视图助手,封装在一个 HTML <dt> 标签里。缺省地,数据预先准备给内容,输出结果基本上是这样的:
<dt><labelfor="foo" class="optional">Foo</label></dt> <dd> <input type="text"name="foo" id="foo" value="123" /> <ul class="errors"> <li>"123" is not analphanumeric value</li> </ul> </dd>
使用同类型的多重装饰器 |
|
在内部,当读取装饰器时,Zend_Form_Element 使用装饰器的类作为查询机制。结果,你不能注册同类型的多重装饰器,后来的装饰器就重写以前存在的装饰器。 为解决这个问题,你可以使用 aliases。不是传递装饰器或装饰器名作为第一个参数给 addDecorator(),而是传递带有一个单个元素的数组,并且别名指向装饰器对象或名字: <?php // Alias to 'FooBar': $element->addDecorator(array('FooBar' => 'HtmlTag'), array('tag' => 'div')); // And retrieve later: $decorator = $element->getDecorator('FooBar'); ?> 在 addDecorators() 和 setDecorators() 方法中,你需要在表示装饰器的数组中传递 ‘decorator‘ 选项: <?php // Add two 'HtmlTag' decorators, aliasing one to 'FooBar': $element->addDecorators( array('HtmlTag', array('tag' => 'div')), array( 'decorator' => array('FooBar' => 'HtmlTag'), 'options' => array('tag' => 'dd') ), ); // And retrieve later: $htmlTag = $element->getDecorator('HtmlTag'); $fooBar = $element->getDecorator('FooBar'); ?> |
装饰器带有的方法包括:
Zend_Form_Element 处理广泛的属性和元素元数据,基本属性包括:
表单元素可能要求另外的元数据。例如,对于 XHTML 表单元素,你可能想指定属性如类或 id,有一组访问器来完成它:
然而大多数时候,你可以把它们当作对象属性来访问,因为 Zend_Form_Element 利用重载来简便访问它们:
<?php // Equivalent to$element->setAttrib('class', 'text'): $element->class ='text; ?>
缺省地,在解析过程中所有属性传递给由元素使用的视图助手,并当作该元素标签的 HTML 属性来解析。
Zend_Form_Element 有许多许多方法。下面是一个快速概要,按类分组:
Zend_Form_Element 的构造器接受选项数组或包含选项的 Zend_Config 的对象,它也可以用 setOptions() 或 setConfig() 来配置。一般来说,命名键如下:
该规则的例外包括如下:
这里是一个例子,为每个配置数据类型传递配置的配置文件:
[element] name ="foo" value ="foobar" label ="Foo:" order = 10 required = true allowEmpty = false autoInsertNotEmptyValidator= true description ="Foo elements are for examples" ignore = false attribs.id ="foo" attribs.class ="element" onclick ="autoComplete(this, '/form/autocomplete/element')" ; sets 'onclick'attribute prefixPaths.decorator.prefix= "My_Decorator" prefixPaths.decorator.path= "My/Decorator/" disableTranslator = 0 validators.required.validator= "NotEmpty" validators.required.breakChainOnFailure= true validators.alpha.validator= "alpha" validators.regex.validator= "regex" validators.regex.options.pattern= "/^[A-F].*/$" filters.ucase.filter= "StringToUpper" decorators.element.decorator= "ViewHelper" decorators.element.options.helper= "FormText" decorators.label.decorator= "Label"
通过继承 Zend_Form_Element 类,你可以生成自己的定制元素,这样做的原因是:
有两个方法一般用来扩展元素:init() 可为元素添加定制的初始化逻辑;loadDefaultDecorators() 可用于设置一个用于元素的缺省装饰器的列表。
用例子来说明,你在一个表单里生成的所有文本元素需要用 StringTrim 来过滤、用通用的规则表达式来校验,并且你想用你生成的定制的装饰器来显示它们,‘My_Decorator_TextItem‘。另外,你有许多想指定的标准属性,包括 ‘size‘、 ‘maxLength‘ 和 ‘class‘。你可以定义这样的元素如下:
<?php class My_Element_Textextends Zend_Form_Element { public function init() { $this->addPrefixPath('My_Decorator','My/Decorator/', 'decorator') ->addFilters('StringTrim') ->addValidator('Regex', false,array('/^[a-z0-9]{6,}$/i')) ->addDecorator('TextItem') ->setAttrib('size', 30) ->setAttrib('maxLength', 45) ->setAttrib('class', 'text'); } } ?>
你接着可以通知表单对象关于元素的前缀路径并开始生成元素:
<?php $form->addPrefixPath('My_Element','My/Element/', 'element') ->addElement('foo', 'text'); ?>
‘foo‘ 元素现在是 My_Element_Text 类型并展示你描画的行为。
当继承 Zend_Form_Element 时你想 override 的另一个特殊方法是 loadDefaultDecorators()。这个方法有条件地为你的元素加载一组缺省装饰器,你可能想在你的继承类里替换你自己的装饰器。
<?php class My_Element_Textextends Zend_Form_Element { public function loadDefaultDecorators() { $this->addDecorator('ViewHelper') ->addDecorator('DisplayError') ->addDecorator('Label') ->addDecorator('HtmlTag',array('tag' => 'div', 'class' => 'element')); } } ?>
版权声明:本文为博主原创文章,未经博主允许不得转载。
使用 Zend_Form_Element 生成表单元素 --(手册)
标签:zend_form_element 生成 生成表单元素 zend framework
原文地址:http://blog.csdn.net/u012675743/article/details/47403407