我有一个这样的自定义验证器设置:
Validator::extend('valid_username', 'ProfileController@valid_username');
然后我有以下方法来处理验证。它会检查用户名是否已存在,以及用户名是否包含有效字符。
public function valid_username($attribute, $value, $parameters)
{
$u = User::where('username', $value)->get();
if ($u->count())
{
// here I would like to return "Username already taken."
return FALSE;
}
else if (preg_match("/^[A-Za-z0-9@\.\-_]+$/", $value))
{
return TRUE;
}
else
{
// here I would like to return "Username contains invalid characters."
return FALSE;
}
}
我想更改此验证程序返回的错误消息,具体取决于导致验证失败的错误。但是,我不知道该怎么做。在我的语言文件中,我为验证器设置了以下行:
"valid_username" => "This username is already taken or contains invalid characters."
Laravel是否可以返回特定的错误消息?或者我是否必须在两个自定义验证规则中拆分此验证?在这种情况下,这可能不是问题,但特别是如果涉及数据库访问,我宁愿在一个验证器中验证检索到的Eloquent模型,而不是两次实例化Eloquent对象。
答案 0 :(得分:8)
在查阅代码后,答案是“没有开箱即用”。但是,您可以扩展所有内容并使其发挥作用。
这个过程,我现在没时间完全做了(抱歉!),就是创建一个扩展Validator的类,使该功能正常工作,然后使用一个新的ServiceProvider用您自己的$app['validator']
替换Laravel的<?php namespace MyLib\Validation;
class Validator extends \Illuminate\Validation\Validator {
// Fancy validation logic to be able to set custom messages
}
。
这个过程,更具体一点,就像这样:
<?php namespace MyLib\Validation;
class Factory extends \Illuminate\Validation\Factory {
// Change this method
/**
* Resolve a new Validator instance.
*
* @param array $data
* @param array $rules
* @param array $messages
* @return \MyLib\Validation\Validator
*/
protected function resolve($data, $rules, $messages)
{
if (is_null($this->resolver))
{
// THIS WILL NOW RETURN YOUR NEW SERVICE PROVIDER SINCE YOU'RE
// IN THE MyLib\Validation NAMESPACE
return new Validator($this->translator, $data, $rules, $messages);
}
else
{
return call_user_func($this->resolver, $this->translator, $data, $rules, $messages);
}
}
}
然后,您需要扩展Factory以返回新的Validator:
<?php namespace MyLib\Validation;
class ValidationServiceProvider extends \Illuminate\Validation\ServiceProvider {
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerPresenceVerifier();
$this->app['validator'] = $this->app->share(function($app)
{
// THIS WILL NOW RETURN YOUR FACTORY SINCE YOU'RE
// IN THE MyLib\Validation NAMESPACE
$validator = new Factory($app['translator'], $app);
// The validation presence verifier is responsible for determining the existence
// of values in a given data collection, typically a relational database or
// other persistent data stores. And it is used to check for uniqueness.
if (isset($app['validation.presence']))
{
$validator->setPresenceVerifier($app['validation.presence']);
}
return $validator;
});
}
}
...最后,扩展验证服务提供程序,使用新的Factory,然后将默认的ValidationServiceProvider替换为您自己的。
Validator::extend()
无论如何,这是使用您自己的代码扩展Validation库的一种方法。我没有解决添加您自己的消息的问题,但是这将告诉您如何阅读核心代码并了解如何添加该功能,以便在您的应用中使其工作。
最后一点:
你可能想看看Laravel如何使用Database "stuff" within validation rules处理 - 虽然这可能不会影响你的应用程序(除非它变大!)你可能想考虑使用某种Repository pattern并使用它在您的User
电话中,而不是直接在{{1}}班级。没必要,只需要注意一些事情。
祝你好运,不要害怕RTFC!
答案 1 :(得分:3)
您可以使用unique
规则,然后制定自己的验证规则,而不是制作自己的验证规则来验证两件事(您不应该这样做,一次验证一件事)。用户名的字符。
例如:
$rules = ['username' => 'required|username|unique:users,username'];
username
规则是您的自定义规则,确保其包含正确的字符。
答案 2 :(得分:0)
可能有点“肮脏”,但它有效:
控制器使用
验证输入$rules = array(
'title' => 'no_collision:'.$input['project_id']
);
在验证器函数中,在返回false之前将消息闪烁到Session:
//...
public function validateNoCollision($attribute, $value, $parameters)
{
$project = Project::find($parameters[0]);
if($value == $project->title){
Session::flash('colliding_message','This collides with '.$project->title($).' created by '.$project->user->name;
return false;
}else{
return true;
}
}
在视图中执行以下操作:
@if($errors->has('title'))
<span class="help-block">{{ Session::get('colliding_message') }}</span>
@endif