zend_form_为Zend_Form_Element设置自定义错误消息

zend_form

In this article I’ll show the solution to a common problem which arises when a developer has to create a non-English website or application that is based on the Zend Framework. How do we mark a field of a Zend_Form which is a Zend_Form_Element as invalid, showing one or more custom error messages? The problem is mainly caused by the native counter-intuitive methods of the Zend_Form_Element class which I’ll explain in more details. (Note the problem and the solution discussed here is valid for Zend Framework version 1.12 and below.)

在本文中,我将为开发人员必须创建基于Zend Framework的非英语网站或应用程序时出现的常见问题提供解决方案。 我们如何标记的领域Zend_Form这是一个Zend_Form_Element为无效,显示一个或多个自定义错误消息? 该问题主要是由Zend_Form_Element类的本机反直觉方法引起的,我将对其进行详细说明。 (请注意,这里讨论的问题和解决方案对于Zend Framework 1.12及更低版本有效。)

开发一个例子 (Developing an Example)

Let’s say that you have a form with different fields and take into account just one of them, for example an text input field used to let a user enter his name. The validators that you can use are different, but for the sake of example we’ll limit the length of the name and it’ll only allow alphabetic characters and spaces. Speaking the Zend Framework language, we’ll use the Zend_Validate_StringLength and the Zend_Validate_Alpha classes respectively.

假设您有一个包含不同字段的表单,并且只考虑其中一个字段,例如,用于让用户输入其姓名的文本输入字段。 您可以使用的验证器是不同的,但是为了举例说明,我们将限制名称的长度,并且仅允许使用字母字符和空格。 说到Zend Framework语言,我们将分别使用Zend_Validate_StringLengthZend_Validate_Alpha类。

As you may already know, Zend Framework is owned by the American company Zend and so all of the messages it shows are in English. The default behavior of the framework is to display one or more error messages for every validator broken by the user input. So, for those who are building a non-English website, there are two options to have messages readable by all users: translate every error message of the framework, or explain in one or more messages that the input is invalid and show suggestions to insert an accepted value. The first option is over-complicated, especially for small and medium-sized projects, so I’ll show how to use the second option.

您可能已经知道,Zend Framework由美国公司Zend拥有,因此它显示的所有消息都是英文的。 框架的默认行为是为每个由用户输入破坏的验证器显示一个或多个错误消息。 因此,对于那些正在建设非英语网站的人,有两种选择可以使所有用户都可以读取消息:翻译框架的每条错误消息,或者在一条或多条消息中解释输入无效,并显示插入建议可接受的值。 第一个选项过于复杂,尤其是对于中小型项目,因此我将展示如何使用第二个选项。

To keep it easy, we will set a single custom message: “The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters.”

为简便起见,我们将设置一条自定义消息:“输入无效。 该值只能包含字母字符和空格,并且长度必须在3到50个字符之间。”

代码 (The Code)

I’ll show the code that we’ll use during the article. First, this is the form that contains the input field for the name and the validators needed to check the data.

我将展示本文中将使用的代码。 首先,此表单包含名称输入字段和检查数据所需的验证器。

<?php
class Application_Form_User extends Zend_Form
{
    public function init() {
        // create the field
        $element = new Zend_Form_Element_Text("name");
        $element->setLabel("Name");

        // set the validators
        $element->setValidators(array(
            new Zend_Validate_Alpha(true),
            new Zend_Validate_StringLength(
                array("min" => 3, "max" => 50))
        ));
        $element->setRequired();

        // add the element to the form
        $this->addElement($element);

        // add a submit button
        $element = new Zend_Form_Element_Submit("submit");
        $element->setLabel("Submit");
        $this->addElement($element);
    }
}

In the controller we’ll check if the field is valid and act accordingly. Usually you won’t use the IndexController and probably you have this validation in a specific controller. Anyway, to simplify the example, I’ll use it.

在控制器中,我们将检查该字段是否有效并采取相应措施。 通常,您不会使用IndexController并且可能在特定控制器中具有此验证。 无论如何,为了简化示例,我将使用它。

<?php
class IndexController extends Zend_Controller_Action
{
    public function init() {
    }

    public function indexAction() {
        $form = new Application_Form_User();

        if ($this->getRequest()->isPost() &&
            $form->isValid($this->getRequest()->getPost())) {
            $this->view->message = "Valid input";
        }
        else {
            $this->view->form = $form;
        }
    }
}

The view used is quite simple; it only shows the message and the form.

使用的视图非常简单; 它仅显示消息和表格。

<?php
if (isset($this->message)) {
    echo $this->message;
}
if (isset($this->form)) {
    echo $this->form;
}

The source code above, without any CSS rule, will render as such:

上面的源代码,没有任何CSS规则,将呈现为:

alt

Moreover, if you insert the invalid value “88” in the Name field you’ll see the messages:

此外,如果在“名称”字段中插入无效值“ 88”,则会看到以下消息:

alt

分析框架的方法 (Analyzing the Framework’s Methods)

A good question to ask is if there are already methods available to face this kind of situation. The answer is almost. I mean there are methods, but they don’t always work as you expect (at least as I expect). The methods to manage the error messages are:

要问的一个好问题是,是否已经有解决这种情况的方法。 答案差不多 。 我的意思是,有一些方法,但是它们并不总是如您所期望的那样工作(至少如我所期望的那样)。 管理错误消息的方法是:

  • setErrors(array $messages)

    setErrors(array $messages)

  • setErrorMessages(array $messages)

    setErrorMessages(array $messages)

The method setErrors() has only one parameter which is an array and uses its elements as messages to show in case of invalid input. An example of its use is:

setErrors()方法只有一个参数,该参数是一个数组,并在无效输入的情况下将其元素用作消息以显示。 其用法的一个示例是:

<?php
// set the custom message in the case of an error
$element->setErrors(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));

This method, as well as displaying the given string(s), also marks the field as invalid.

此方法,以及显示给定的字符串,也将该字段标记为无效。

It can be used at two times in the application logic, but in both it has a behavior which is not useful for our goal. The first is during the creation of the form element (init() method). In this case the message is shown when the form has been loaded and before the user has inserted any data. Quite unpleasant. In this case the relevant part of code changes like this:

它可以在应用程序逻辑中两次使用,但是在两种情况下,它的行为对于我们的目标都没有用。 首先是在创建表单元素( init()方法)期间。 在这种情况下,将在加载表单时以及用户插入任何数据之前显示该消息。 相当不愉快。 在这种情况下,代码的相关部分将如下更改:

<?php
// set the validators
$element->setValidators(array(
    new Zend_Validate_Alpha(true),
    new Zend_Validate_StringLength(
        array("min" => 3, "max" => 50))
));
$element->setRequired();

// set the custom message in the case of an error
$element->setErrors(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));

The second time occurs after the information has been sent during the usual data validation within the controller. What happens is that the custom message is appended to the default ones when an error occurs. In this case, the indexAction() of the IndexController changes in this way:

第二次是在控制器内进行常规数据验证期间发送信息之后发生的。 发生的情况是,发生错误时,自定义消息会附加到默认消息之后。 在这种情况下, IndexControllerindexAction()以这种方式更改:

<?php
public function indexAction() {
    $form = new Application_Form_User();
    if ($this->getRequest()->isPost()) {
        // If the input of the user is valid, set the success
        // message. Otherwise, set the custom errors and show
        // the form again.
        if ($form->isValid($this->getRequest()->getPost())) {
            $this->view->message = "Valid input";
        }
        else {
            $form->getElement("name")->setErrors(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));
            $this->view->form = $form;
        }
    }
    else {
        $this->view->form = $form;
    }
}

Just like setErrors(), the setErrorMessages() method take as a parameter an array of strings which will be shown to the user in case of invalid input. An example of its use is:

就像setErrors()setErrorMessages()方法将一个字符串数组作为参数,如果输入无效,该字符串数组将显示给用户。 其用法的一个示例是:

<?php
$element->setErrorMessages(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));

This line of code still doesn’t solve the problem beucase it will either show the same error message for every not-satisfied condition or it will have no effect. If the line shown is used in the init() method, in the same way shown for the setErrors(), in case of error, the custom message will be shown as many times as the number of conditions violated by the user input. If the line is inserted during the usual data validation within the controller, in the same way explained before, there will be no effect. This means that the custom message won’t be displayed and the framework will show only the default messages.

这行代码仍然不能解决问题,因为它对每个未满足的条件都将显示相同的错误消息,否则将无效。 如果在init()方法中使用显示的行,则与setErrors()所示的方式相同,在发生错误的情况下,自定义消息的显示次数将是用户输入违反条件的次数。 如果以常规方式在控制器内进行常规数据验证时插入了该行,则不会产生任何影响。 这意味着将不会显示自定义消息,并且框架将仅显示默认消息。

发现解决方案 (Uncovering the Solution)

Now the point is to understand when and how to insert the custom message so that the user can have a comparison and a suggestion about what values are accepted. Definitely, the when lies in the creation of the field inside the form (init() method) and the how is due to the union of the setErrorMessages() method and the use of a property of the validators of Zend Framework called breakChainOnFailure(). The latter allows us to stop the validation process at the first failed condition. If we set up five validators but the first of them fails, the other four won’t be used.

现在,关键是要了解何时以及如何插入自定义消息,以便用户可以进行比较并提出关于接受哪些值的建议。 breakChainOnFailure()表单( init()方法)内部字段的创建,而方式setErrorMessages()方法的联合以及使用Zend Framework验证器的属性breakChainOnFailure() 。 后者使我们可以在第一个失败的条件下停止验证过程。 如果我们设置了五个验证器,但第一个验证器失败,则将不使用其他四个验证器。

To employ this property making use of the smallest possible number of code lines, I’ll change a little bit the code I have illustrated at the beginning. I’ll add to the init() method the code line which uses the setErrorMessages() method, and I’ll take advantage of one of the possible input configurations accepted by setValidators() which expects an array of arrays. The array contained in the main one can have a maximum of three parameters, which are:

为了利用尽可能少的代码行数来利用此属性,我将稍微更改我在开始时说明的代码。 我将使用setErrorMessages() init()方法的代码行添加到init()方法中,并且将利用setValidators()接受的可能的输入配置之一,该配置期望使用数组数组。 主数组中包含的数组最多可以具有三个参数,它们是:

  1. A string (mandatory) to specify the validator to user.

    一个字符串(强制性),用于向用户指定验证器。
  2. A boolean (optional, by default its value is false) to specify if the framework has to break the validation at the first failure or not. Thus, this parameter sets the value of the property breakChainOnFailure which is what will help us in achieve our goal.

    布尔值(可选,默认情况下,其值为false ),用于指定框架在第一次失败时是否必须中断验证。 因此,此参数设置属性breakChainOnFailure的值,这将有助于我们实现目标。

  3. An array of options (optional, by default an empty array) different for every choosen validator

    每个选择的验证程序都不同的选项数组(可选,默认为空数组)

Using the second parameter passed as true for each of the validators that you want to use is essential.

必须为要使用的每个验证器使用传递为true的第二个参数。

According to what we’ve seen until now, the resulting code is:

根据我们到目前为止所看到的,结果代码为:

<?php
class Application_Form_User extends Zend_Form
{
    public function init() {
        // create the field
        $element = new Zend_Form_Element_Text("name");
        $element->setLabel("Name");

        // set the validators
        $element->setValidators(array(
            array("Alpha", true, array("allowWhiteSpace" => true)),
            array("StringLength", true, array(
                "min" => 3, "max" => 50))
        ));
        $element->setRequired();

        // set the custom message in the case of an error
        $element->setErrorMessages(array("The input is invalid. The value must have only alphabetic characters and spaces and its length must be between 3 and 50 characters."));

        // add the element to the form
        $this->addElement($element);

        // add a submit button
        $element = new Zend_Form_Element_Submit("submit");
        $element->setLabel("Submit");
        $this->addElement($element);
    }
}

结论 (Conclusion)

Using the code above, the form will show only the custom message when there’s invalid input… exactly what we wanted! In case you need to use more messages, for example suggestions in several stages, just add more strings to the array used for the setErrorMessages() method.

使用上面的代码,当输入无效时,表单将仅显示自定义消息……正是我们想要的! 如果您需要使用更多消息,例如分几个阶段的建议,只需将更多字符串添加到用于setErrorMessages()方法的数组中即可。

Image via Fotolia

图片来自Fotolia

翻译自: https://www.sitepoint.com/setting-custom-error-messages-for-zend_form_element/

zend_form

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值