我有一个表单,它有一个输入"数组",提交时,使用Laravel的验证器进行验证。
验证按预期工作,将规则应用于每个数组元素,并相应地返回错误的 MessageBag。
问题:MessageBag 不引用数组的相关索引。有没有办法(除了为数组的每个可能的索引定义规则)让Laravel引用相关的输入数组索引?
示例网页
<input name="something[]" type="text" />
<input name="something[]" type="text" />
<input name="something[]" type="text" />
...
样品验证器
Validator::make
(
Input::all(),
array
(
"something" => array("required", "exists:somewhere")
)
);
验证后的示例消息包(不引用输入数组索引)
object(Illuminate'Support'MessageBag)#150 (2)
{
["messages":protected]=> array(6)
{
["something"]=> array(1)
{
[0]=> string(26) "Some error message"
}
}
...
}
我未能找到任何使用标准 Laravel 核心功能执行此操作的方法,因此我最终扩展了 Validator
类以实现解决方案。
为了更好地理解此解决方案,记录了下面的代码。
-
创建
app/libraries/MyApp/Validation
目录以保存新类 -
本文的扩展
'Illuminate'Validation'Validator
("从类解析"方法):扩展Laravel 4验证器 -
覆盖
Validator#passes()
namespace MyApp'Validation; use 'Illuminate'Validation'Validator; class ArrayAwareValidator extends Validator { //Override Validator#passes() method public function passes() { //For each validation rule... foreach ($this->rules as $attribute => $rules) { //Get the value to be validated by this rule $values = $this->getValue($attribute); //If the value is an array, we got an HTML input array in our hands if(is_array($values)) { //Iterate through the values of this array... for($i=0; $i<count($values); $i++) { //...and create a specific validation rule for this array index $this->rules[$attribute.".".$i] = $rules; } //Delete original rule unset($this->rules[$attribute]); } } //Let Validator do the rest of the work return parent::passes(); } }
-
这将导致以下
MessageBag
object(Illuminate'Support'MessageBag)#151 (2) { ["messages":protected]=> array(2) { ["something.0"]=> array(1) { [0]=> string(26) "Some error message" } ["something.1"]=> array(1) { [0]=> string(26) "Some error message" } } ... }
-
在客户端,使用 JavaScript,我将名称从索引中拆分(例如"something.1"到"something"和"1"),然后使用此信息来识别正确的表单输入。我正在使用 Ajax 提交表单,因此您可能需要在此处使用不同的方法。
注意:这是一个务实的解决方案,非常适合我的问题。如您所见,数组索引与同一字符串中的输入名称一起传递。您可能希望进一步扩展内容,以便Validator
返回具有名称和索引作为单独内容的对象或数组。
你的验证器应该是这样的:
Validator::make
(
Input::all(),
array
(
'something' => 'required,unique:somewhere'
));