更好地控制自定义 Laravel 5 验证的错误消息

Better control on error message on Custom Laravel 5 validation

我在我的 AppServiceProvider@boot 中定义了一个自定义验证器,如下所示

/* Custom unique value in set of fields validation */
Validator::extend('unique_in', function ($attribute, $value, $parameters, $validator) {
    $validator_data = $validator->getData();
    foreach ($parameters as $field) {
        if ($value === array_get($validator_data, $field)) {
            return false;
        }
    }
    return true;
}, 'The :attribute cannot be same as any other field in this form.');

/* replace the :fields message string */
Validator::replacer('unique_in', function ($message, $attribute, $rule, $parameters) {
    // I was doing this (this works)
    //    $message = str_replace(':field', implode(',',$parameters), $message);
    //    return $message;

    //I want to do this (to get proper names for the fields)
    $other = $this->getAttribute(array_shift($parameters));

    return str_replace([':other', ':values'], [$other, implode(', ', $parameters)], $message);
});

问题是无法访问验证器实例 getAttribute。 getAttribute 解析参数的可读名称

是否可以访问替换器中的验证器实例?

请注意,Validator::extend 中的闭包有 $validator,它是验证器的一个实例。

我使用 getCustomMessagesetCustomMessage 使它工作,但没有使用 Validator::replacer 单独使用 Validator::extend

Validator::extend('unique_in', function ($attribute, $value, $parameters, $validator) {
        $validator_data = $validator->getData();
        $parameters = array_diff($parameters, [$attribute]);
        $same = null;
        $other = null;
        foreach ($parameters as $field) {
            if ($value === array_get($validator_data, $field)) {
                $same[] = $field;
            }
        }
//No same values found , validation success
        if (is_null($same)) {
            return true;
        }

// Get all Custom Attributes those are defined for this validator and replace with field in $same array and create a new $other array
        $custom_attributes = $validator->getCustomAttributes();
        foreach ($same as $attribute) {
            $other[$attribute] = isset($custom_attributes[$attribute]) ? $custom_attributes[$attribute] : $attribute;
        }

//Task of Validator:replacer is done right here.
        $message = 'The :attribute cannot have same value ":value" as in :fields';
        $message = str_replace([':value',':fields'], [$value ,implode(', ', $other)], $message);
        $validator->setCustomMessages(array_merge($validator->getCustomMessages(), ['unique_in' => $message]));

        return false;
    });

谢谢,

K

我知道这个帖子有点老,已经回答过了,但是我在搜索这个问题的答案时想到的第一个。

我想分享我的解决方案。我在 Validator::replacer 闭包中使用 Laravel 5.4 的本地化,如下所示:

Validator::extend('empty_when', function ($attribute, $value, $parameters) {
    foreach ($parameters as $key) {
        if ( ! empty(Input::get($key))) {
            return false;
        }
    }

    return true;
});

Validator::replacer('empty_when', function ($message, $attribute, $rule, $parameters) {
    $fields = [];
    foreach ($parameters as $parameter) {
        $fields[] = __('validation.attributes.'.$parameter);
    }
    return str_replace(':values', implode(', ', $fields), $message);
});

使用反式()。你可以简单地这样做:

Validator::replacer('greater_than', function($message, $attribute, $rule, $parameters) {
    return str_replace(':field', trans('validation.attributes.'.$parameters[0]), $message);
});