如何在 Laravel 中使用 setter 方法设置验证规则?
Posted
技术标签:
【中文标题】如何在 Laravel 中使用 setter 方法设置验证规则?【英文标题】:How to set the validation rules using a setter method in Laravel? 【发布时间】:2016-01-18 10:01:05 【问题描述】:我需要使用setter方法在Validator Class中设置$rules
数组。
我需要使用 setter 设置定义的 $rules,因为规则存储在数据库中。我需要使用 Eloquent 来查询数据库以确定规则是什么样的。
我扩展了 Validator 类并添加了一个名为 setCustomRules() 的方法。我在这个方法中注入了一个类,这将允许我使用 Eloquent 读取数据库以确定规则。
但是,当 Laravel 尝试验证时,我将如何强制触发 setCustomRules() 方法?必须先执行此方法,以确保在进行验证之前设置规则。
这就是我所做的
<?php namespace Vend\Surveys\Validator\SurveyAnswers;
use Cartalyst\Support\Validator;
use Vend\Surveys\Repositories\SurveyAnswers\SurveyAnswerDefinedRepository;
class SurveyAnswerDefinedValidator extends Validator implements SurveyAnswerDefinedValidatorInterface
/**
* @inheritDoc
*/
protected $rules;
/**
* @inheritDoc
*/
public function onUpdate()
public function setCustomRules(SurveyAnswerDefinedRepository $rules)
foreach($rules as $rule)
$this->rules[$rule->name] = $rule->spec;
//this should display the rules that will be used to validate the form
dd($this->rules);
已编辑 根据 The Alpha 的回答,我创建了一个事件处理程序,可以让我创建规则。但不知道如何告诉 Laravel 现在进行验证。
这是我的 EventHandler 类
<?php namespace vend\Surveys\Handlers\SurveyAnswers;
use Illuminate\Events\Dispatcher;
use vend\Surveys\Models\SurveyAnswerDefined;
use Cartalyst\Support\Handlers\EventHandler as BaseEventHandler;
use vend\Surveys\Repositories\SurveyQuestions\SurveyQuestionsRepositoryInterface;
class SurveyAnswerDefinedEventHandler extends BaseEventHandler implements SurveyAnswerDefinedEventHandlerInterface
protected $rules = [];
/**
* @inheritDoc
*/
public function subscribe(Dispatcher $dispatcher)
$dispatcher->listen('vend.surveys.surveyanswerdefined.creating', __CLASS__.'@creating');
$dispatcher->listen('vend.surveys.surveyanswerdefined.created', __CLASS__.'@created');
$dispatcher->listen('vend.surveys.surveyanswerdefined.updating', __CLASS__.'@updating');
$dispatcher->listen('vend.surveys.surveyanswerdefined.updated', __CLASS__.'@updated');
$dispatcher->listen('vend.surveys.surveyanswerdefined.deleted', __CLASS__.'@deleted');
/**
* @inheritDoc
*/
public function creating(SurveyQuestionsRepositoryInterface $questions, array $data)
$this->setRules($questions);
dd($this->rules);
/**
* @inheritDoc
*/
public function created(SurveyAnswerDefined $surveyanswers)
$this->flushCache($surveyanswers);
/**
* @inheritDoc
*/
public function updating(SurveyAnswerDefined $surveyanswers, array $data)
$this->setRules($questions);
dd($this->rules);
/**
* @inheritDoc
*/
public function updated(SurveyAnswerDefined $surveyanswers)
$this->flushCache($surveyanswers);
/**
* @inheritDoc
*/
public function deleted(SurveyAnswerDefined $surveyanswers)
$this->flushCache($surveyanswers);
/**
* Flush the cache.
*
* @param \vend\Surveys\Models\Surveyanswers $surveyanswers
* @return void
*/
protected function flushCache(SurveyAnswerDefined $surveyanswers)
$this->app['cache']->forget('vend.surveys.surveyanswerdefined.all');
$this->app['cache']->forget('vend.surveys.surveyanswerdefined.'.$surveyanswers->id);
private function setRules($questions)
foreach($questions as $question)
foreach($questions->controls as $control)
$this->rules['control_' . $control->id] = $this->makeRules($control);
private function makeRules($control)
$rules = [];
if($control->is_required)
$rules[] = 'required';
if($control->validation_rule == 'Text')
if($control->min_length)
$rules[] = 'min:' . $control->max_length;
if($control->max_length)
$rules[] = 'max:' . $control->max_length;
if($control->validation_rule == 'Number')
$rules[] = 'numeric';
if($control->min_value)
$rules[] = 'min:' . $control->max_length;
if($control->max_value)
$rules[] = 'max:' . $control->max_length;
【问题讨论】:
【参考方案1】:您可以 (IMO) 使用模型事件,例如:保存时(适用于创建和更新)您可以调用 setCustomRules
方法来设置和验证规则,如下所示:
public static function boot()
parent::boot();
// This method will be called on creating and updating
// but there are separate events for both methods so you
// may use separate handlers for different events like :
// static::creating(...) static::updating(...)
static::saving(function($user)
// Set rules and validate here
);
这应该在模型中,还有其他注册事件的方法,但我最喜欢这种方式。欲了解更多信息,请查看Laravel Website@Events
【讨论】:
如果我理解 laravel laravel.com/docs/5.1/lifecycle 中的请求生命周期,验证步骤发生在任何数据库操作之前。因此,如果有错误,Laravel 将生成错误,然后将用户发送到视图或将每个内容返回给控制器的方法。因此,如果验证发生在任何 SQL 操作之前,您的建议将导致验证两次,一次是默认 Laravel 步骤,然后是保存前的步骤。我在这里错过了什么? 不,如果您注册这些事件,那么它会以这种方式工作。例如,在引导方法中,如果您注册了creating(function()...)
,那么在创建新模型之前,该函数将被执行。如果您从该函数返回 false,则 create 将被中断,这意味着不会为无效数据保存新模型。你需要手动捕捉它。
我想我明白了。那么如何将 SurveyAnswerDefinedRepository 类注入到 save() 事件中,以便读取数据库中的规则?
将规则传递给该模型或从模型本身中获取规则,只需尝试一下,阅读文档以获取更多信息,我相信您可以做到 :-)跨度>
我想我跟着你。好吧,我希望我是 :) 我创建了创建、更新事件处理程序,并注入了允许我获取规则的类。如何设置规则或告诉 Laravel 现在进行验证?我的意思是我将如何触发验证器?我会用我的代码更新我的问题【参考方案2】:
迟到的答复
您也可以使用Model Mutators 并进行验证
例如
public function setFirstNameAttribute($value)
// validate $value e.g.:
if (strlen($value) < 2)
throw new \Exception('name too short, 2 char minimum');
【讨论】:
以上是关于如何在 Laravel 中使用 setter 方法设置验证规则?的主要内容,如果未能解决你的问题,请参考以下文章
axios请求给getter setter方法而不是查询数据