关于学说验证的自定义错误消息

riz*_*oro 3 php doctrine

我需要修改doctrine验证的默认错误消息.我怎样才能做到这一点?

谢谢

Pas*_*TIN 6

CrazyJoe某种程度上是正确的:没有一些努力工作是不可能的:-(

但是,如果你搜索得足够多,你可能会找到一种方法;-)


使用Doctrine 1.1,您可以扩展类模型Doctrine_Record.
该类定义了此方法:

/**
 * Get the record error stack as a human readable string.
 * Useful for outputting errors to user via web browser
 *
 * @return string $message
 */
public function getErrorStackAsString()
{
    $errorStack = $this->getErrorStack();

    if (count($errorStack)) {
        $message = sprintf("Validation failed in class %s\n\n", get_class($this));

        $message .= "  " . count($errorStack) . " field" . (count($errorStack) > 1 ?  's' : null) . " had validation error" . (count($errorStack) > 1 ?  's' : null) . ":\n\n";
        foreach ($errorStack as $field => $errors) {
            $message .= "    * " . count($errors) . " validator" . (count($errors) > 1 ?  's' : null) . " failed on $field (" . implode(", ", $errors) . ")\n";
        }
        return $message;
    } else {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是生成消息的方法; 如你所见,它是全自动的,根本不可配置:-(


不过,多亏了OOP,我们可以在Model类中重载该方法...

但是,为了更清洁,我会:

  • 创建一个新类 - 比方说My_Doctrine_Record,扩展Doctrine_Record
  • 该类将重新定义该方法,以允许自定义错误消息
  • 我们的Model类将扩展My_Doctrine_Record该类.

这样可以避免在每个模型类中重复该方法; 并可能在另一天证明有用......


My_Doctrine_Record::getErrorStackAsString当然, 我们的方法可以依赖于我们的模型类的方法,以帮助生成消息,并为每个模型类进行特殊定制.

这是一个有效的例子; 远非完美,但它可能会引导你到达你想要的东西;-)


首先,初始化:

require_once '/usr/share/php/Doctrine/lib/Doctrine.php';
spl_autoload_register(array('Doctrine', 'autoload'));

$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);

$conn = Doctrine_Manager::connection('mysql://test:123456@localhost/test1');
Run Code Online (Sandbox Code Playgroud)

我猜你的应用已经有了类似的东西......


接下来,我们的新My_Doctrine_Record课程:

class My_Doctrine_Record extends Doctrine_Record
{
    public function getErrorStackAsString()
    {
        $errorStack = $this->getErrorStack();
        if (count($errorStack)) {
            $message = sprintf("BAD DATA in class %s :\n", get_class($this));
            foreach ($errorStack as $field => $errors) {
                $messageForField = $this->_getValidationFailed($field, $errors);
                if ($messageForField === null) {
                    // No custom message for this case => we use the default one.
                    $message .= "    * " . count($errors) . " validator" . (count($errors) > 1 ?  's' : null) . " failed on $field (" . implode(", ", $errors) . ")\n";
                } else {
                    $message .= "    * " . $messageForField;
                }
            }
            return $message;
        } else {
            return false;
        }
    }

    protected function _getValidationFailed($field, $errors) {
        return null;
    }

}
Run Code Online (Sandbox Code Playgroud)

您会注意到该getErrorStackAsString方法的灵感来自Doctrine提供的方法 - 这看起来很正常,我会说^^

还有一点需要注意:

  • 它定义并调用_ getValidationFailed方法
  • 那个人应该创建错误信息; 或者null如果我们想要使用默认的行为,则返回
  • 我们可以_getValidationFailed在我们的Model类中重载该方法,以定制东西;-)


现在,我的Model类:

class Test extends My_Doctrine_Record
{
    protected function _getValidationFailed($field, $errors) {
        switch ($field) {
            case 'name': 
                    return "You entered wrong data from 'name' field.\n      Errors are for '" 
                        . implode("', '", $errors) . "'\n";
                break;
            // other fields ?
            default:
                return null;
        }
    }

    public function setTableDefinition()
    {
        $this->setTableName('test');
        $this->hasColumn('id', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'unsigned' => 0,
             'primary' => true,
             'autoincrement' => true,
             ));
        $this->hasColumn('name', 'string', 32, array(
             'type' => 'string',
             'length' => 32,
             'fixed' => false,
             'notnull' => true,
             'email'   => true,
             ));
        $this->hasColumn('value', 'string', 128, array(
             'type' => 'string',
             'length' => 128,
             'fixed' => false,
             'notnull' => true,
             'htmlcolor' => true,
             ));
        $this->hasColumn('date_field', 'integer', 4, array(
             'type' => 'timestamp',
             'notnull' => true,
             ));
    }
}
Run Code Online (Sandbox Code Playgroud)

它扩展My_Doctrine_Record并定义了一个_getValidationFailed方法,用于处理name模型字段上的验证错误.


现在,让我们假设我这样做来加载记录:

$test = Doctrine::getTable('Test')->find(1);
var_dump($test->toArray());
Run Code Online (Sandbox Code Playgroud)

让我们尝试修改它,设置"坏"值:

$test->name = (string)time();
$test->value = 'glop';
try {
    $test->save();
} catch (Doctrine_Validator_Exception $e) {
    echo '<pre>';
    echo $e->getMessage();
    echo '</pre>';
    die;
}
Run Code Online (Sandbox Code Playgroud)

两个namevalue字段都不正常...所以,我们将通过我们的验证方法,并生成此错误消息:

BAD DATA in class Test :
    * You entered wrong data from 'name' field.
      Errors are for 'email'
    * 1 validator failed on value (htmlcolor)
Run Code Online (Sandbox Code Playgroud)

您可以看到" name" 的消息已经自定义," " 的消息value来自默认的Doctrine事物.


所以,总结:不容易,但可行;-)

而且,现在,由您来决定使用它作为问题的确切解决方案的指南:-)
它需要更多的编码,我想......但是你离真正的交易并不遥远!

玩得开心 !