有一個問題與接受的答案(和Laravel的驗證一般來講,在我看來) - 驗證過程本身,並驗證狀態檢測合併成一個方法。
如果您盲目渲染包中的所有驗證消息,這沒什麼大不了的。但是,如果您有一些額外的邏輯來檢測驗證器是否失敗並執行其他操作(例如爲當前驗證的表單域提供國際短信),那麼您遇到了問題。
演示:
// let's create an empty validator, assuming that we have no any errors yet
$v = Validator::make([], []);
// add an error
$v->errors()->add('some_field', 'some_translated_error_key');
$fails = $v->fails(); // false!!! why???
$failedMessages = $v->failed(); // 0 failed messages!!! why???
此外,
$v->getMessageBag()->add('some_field', 'some_translated_error_key');
產生相同的結果。爲什麼?因爲如果你看看Laravel的驗證碼,你會發現以下內容:
public function fails()
{
return ! $this->passes();
}
public function passes()
{
$this->messages = new MessageBag;
正如你所看到的,fails()
方法基本上清除掉袋失去所有你已經附加了報文,從而使驗證假設有沒有錯誤。
沒有辦法將錯誤追加到現有驗證器並使其失敗。您只能創建一個新的驗證,像這樣的自定義錯誤:
$v = Validator::make(['some_field' => null],
['some_field' => 'Required:some_translated_error_key']);
$fails = $v->fails(); // true
$failedMessages = $v->failed(); // has error for `required` rule
如果你不喜歡濫用定製附加誤差required
驗證規則的想法,你總是可以使用自定義規則擴展Laravel驗證。我添加了一個通用的failkey
規則,並使其強制性這樣:
// in custom Validator constructor: our enforced failure validator
array_push($this->implicitRules, "Failkey");
...
/**
* Allows to fail every passed field with custom key left as a message
* which should later be picked up by controller
* and resolved with correct message namespaces in validate or failValidation methods
*
* @param $attribute
* @param $value
* @param $parameters
*
* @return bool
*/
public function validateFailkey($attribute, $value, $parameters)
{
return false; // always fails
}
protected function replaceFailkey($message, $attribute, $rule, $parameters)
{
$errMsgKey = $parameters[0];
// $parameters[0] is the message key of the failure
if(array_key_exists($errMsgKey, $this->customMessages)){
$msg = $this->customMessages[$parameters[0]];
}
// fallback to default, if exists
elseif(array_key_exists($errMsgKey, $this->fallbackMessages)){
return $this->fallbackMessages[$parameters[0]];
}
else {
$msg = $this->translator->trans("validation.{$errMsgKey}");
}
// do the replacement again, if possible
$msg = str_replace(':attribute', "`" . $this->getAttribute($attribute)
. "`", $msg);
return $msg;
}
而且我可以這樣使用它:
$v = Validator::make(['some_field' => null],
['some_field' => 'failkey:some_translated_error_key']);
$fails = $v->fails(); // true
$failedMessages = $v->failed(); // has error for `Failkey` rule
當然,這仍然是解決這一問題的哈克的方式。
理想情況下,我會重新設計驗證(對於validate()
和passes()
或更好isValid()
單獨的方法),以明確地分開狀態檢測其驗證階段,並且還添加方便的方法來手動故障與特定的規則的特定字段。雖然這也可能會被認爲是hacky,但是如果我們想要使用Laravel驗證器不僅僅是Laravel自己的驗證規則,還有我們的自定義業務邏輯規則,我們也別無選擇。
不知道爲什麼我需要檢查電子郵件,但郵件包的東西工作,謝謝。 :) –
這很酷。我仍然不會傾向於混合我的驗證錯誤和應用程序消息。 –
這太棒了。 – enchance