在替换器中获取验证失败的值的访问权



当在Laravel中使用自定义验证规则和替换器时,我真的很难找到任何文档,可以简单地让您获得验证失败的值。

例如,我创建了一个文件存在验证器:
Validator::extend('view_exists', function($field,$value,$parameters) 
{
    return View::exists($value);
});
Validator::replacer('view_exists', function($message, $attribute, $rule, $parameters)
{
    return str_replace(':filename', 'THE ENTERED VALUE', $message);
});

现在,当我创建一个规则:

$rules = array('filename' => 'required|view_exists');
$messages = array('filename.view_exists' => 'Filename ':filename' does not exist');

当我输入一个无效的路径时,比如safsakjhdsafkljh,我希望它能返回

Filename 'safsakjhdsafkljh' does not exist

但是replacer无法访问验证失败的值。我已经尝试输出传递给闭包的所有参数,包括$this,它不在哪里可以看到:(

在我使用Input::get(呃)之前,我错过了一些完全明显的东西吗?

感谢

Gavin

使用Laravel 5.4,您可以像下面这样在replacer回调中访问Validator实例:

Validator::replacer('view_exists', function ($message, $attribute, $rule, $parameters, Validator $validator) {
    $value = array_get($validator->getData(), $attribute);
    return str_replace(':filename', $value, $message);
});

你可以这样做(Laravel 5.2):

Validator::extend('my_custom_validation_rule', function($attribute, $value, $parameters, $validator) {
    $validator->addReplacer('my_custom_validation_rule', function ($message, $attribute, $rule, $parameters) use ($value) {
        return str_replace(':value', $value, $message);
    });
    return $value == 'foo';
});

翻译文件:

'my_custom_validation_rule' => ':value is not correct value.'

我怀疑我最初的想法是唯一的方法,但如果有人能提出其他建议,我将不胜感激:

我的解决方案是:

Validator::extend('view_exists', function($field,$value,$parameters) 
{
    return View::exists($value);
});
Validator::replacer('view_exists', function($message, $attribute, $rule, $parameters)
{
    return str_replace(':filename', Input::get($attribute), $message);
});

不是最好的,但是,嘿,它工作…

使用Validator类中的 getValue() 方法。要做到这一点,请遵循两个步骤:

第一个

创建你自己的CustomValidator类,它扩展了Laravel的IlluminateValidationValidator基类:

Validator::resolver(function($translator, $data, $rules, $messages, $attributes)
{
    return new CustomValidator($translator, $data, $rules, $messages, $attributes);
});

或者service provider:

public function boot()
{
    $this->app->validator->resolver(function($translator, $data, $rules, $messages, $attributes)
    {
        return new CustomValidator($translator, $data, $rules, $messages, $attributes);
    });
}

第二

创建CustomValidator类,例如在app/Validation/CustomValidator.php中,使用替换方法:

<?php namespace AppValidation;
use IlluminateValidationValidator;
class CustomValidator extends Validator {
    /**
     * Replace all place-holders for the view_exists rule.
     *
     * @param  string  $message
     * @param  string  $attribute
     * @param  string  $rule
     * @param  array   $parameters
     * @return string
     */
    protected function replaceViewExists($message, $attribute, $rule, $parameters)
    {
        return str_replace(':value', $this->getValue($attribute), $message);
    }
}

正如@Bald所说,您可以使用Validator::extend()方法中的第四个参数来添加自定义替换器。这是很好的,特别是当您对自定义验证进行了一些查询,并且希望使用查询结果来生成更具表现力的错误消息时。

的例子:

Validator::extend('unique_view_filename', function($field,$value,$parameters,$validator){
    $result = View::where($field, $value)->first();
    if($result){
        $validator->addReplacer('unique_view_filename',  function ($message, $attribute, $rule, $parameters) use ($result) {
            return str_replace([':filename', ':id'], [$result->filename, $result->id], $message);
        });
        return false;
    }
    return true;
});

在你的翻译文件中:

'unique_view_filename' => ':filename already exists (File ID: :id).'

一个很傻的例子,但是你明白了基本的意思